您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add a document scanning button to your web pages with Dynamic Web TWAIN.
// ==UserScript== // @name Document Scanner // @namespace https://www.dynamsoft.com // @version 0.3 // @description Add a document scanning button to your web pages with Dynamic Web TWAIN. // @author Lihang Xu // @include * // @license MIT // @icon https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net // @grant GM_addStyle // ==/UserScript== let modal; let DWObject; const CSS = /* css */ ` .dwt-fab { position:fixed; bottom:0; width: 50px; height: 50px; left: 0; margin: 10px; border-radius: 50%; background: #2196f3; pointer-events: auto; z-index: 9999; } .dwt-fab:hover { background: #7db1d4; } .dwt-fab img { padding: 10px; } .dwt-modal { position:fixed; left: 20px; top: 20px; width: calc(100% - 40px); height: calc(100% - 40px); border: 1px solid gray; border-radius: 5px; background: white; z-index: 9999; } .dwt-header { height: 25px; } .dwt-close-btn { float: right; margin-right: 5px; } .dwt-body { text-align: center; height: calc(100% - 25px); } .dwt-controls { text-align: center; height: 50px; } #dwtcontrolContainer { width: 100%; height: calc(100% - 50px); } `; (function() { 'use strict'; GM_addStyle(CSS); console.log("DWT userscript loaded"); init(); // Your code here... })(); async function init(){ await loadLibrary("https://unpkg.com/[email protected]/dist/dynamsoft.webtwain.min.js","text/javascript"); Dynamsoft.DWT.AutoLoad = false; Dynamsoft.DWT.ResourcesPath = "https://unpkg.com/[email protected]/dist"; addButton(); } function addButton(){ const button = document.createElement("div"); button.className = "dwt-fab"; const a = document.createElement("a") a.href = "javascript:void(0)"; const icon = document.createElement("img") icon.src = "https://tony-xlh.github.io/document-scanner-userscript/scanner-scan.svg" a.appendChild(icon); button.appendChild(a); document.body.appendChild(button); button.addEventListener("click", () => { showModal(); }); } function showModal(){ if (!modal) { modal = document.createElement("div"); modal.className = "dwt-modal"; document.body.appendChild(modal); const header = document.createElement("div"); const closeBtn = document.createElement("div"); closeBtn.className = "dwt-close-btn"; closeBtn.innerText = "x"; header.appendChild(closeBtn); header.className = "dwt-header"; closeBtn.addEventListener("click", () => { hideModal(); }); const body = document.createElement("div"); body.className = "dwt-body"; const viewer = document.createElement("div"); viewer.id = "dwtcontrolContainer"; const controls = document.createElement("div"); controls.className = "dwt-controls"; const scanBtn = document.createElement("button"); scanBtn.innerText = "Scan"; scanBtn.addEventListener("click", () => { scan(); }); const copyBtn = document.createElement("button"); copyBtn.innerText = "Copy selected"; copyBtn.addEventListener("click", () => { copy(); }); const saveBtn = document.createElement("button"); saveBtn.innerText = "Save"; saveBtn.addEventListener("click", () => { save(); }); const status = document.createElement("div"); status.className="dwt-status"; controls.appendChild(scanBtn); controls.appendChild(copyBtn); controls.appendChild(saveBtn); controls.appendChild(status); body.appendChild(viewer); body.appendChild(controls); modal.appendChild(header); modal.appendChild(body); if (!DWObject) { initDWT(); } } document.querySelector(".dwt-fab").style.display = "none"; modal.style.display = ""; } function hideModal(){ modal.style.display = "none"; document.querySelector(".dwt-fab").style.display = ""; } function scan(){ if (DWObject) { if (Dynamsoft.Lib.env.bMobile) { DWObject.Addon.Camera.scanDocument(); }else { DWObject.SelectSource(function () { DWObject.OpenSource(); DWObject.AcquireImage(); }, function () { console.log("SelectSource failed!"); } ); } } } function copy(){ if (DWObject) { if (Dynamsoft.Lib.env.bMobile) { DWObject.ConvertToBlob( [DWObject.CurrentImageIndexInBuffer], Dynamsoft.DWT.EnumDWT_ImageType.IT_PNG, function(result) { CopyBlobToClipboard(result); }, function(errorCode,errorString) { console.log("convert failed"); console.log(errorString); alert("Failed"); }); }else{ DWObject.CopyToClipboard(DWObject.CurrentImageIndexInBuffer); alert("Copied"); } } } function CopyBlobToClipboard(blob) { var data = [new ClipboardItem({ "image/png": blob})]; navigator.clipboard.write(data).then(function() { alert("Copied"); }, function() { alert("Failed"); }); } function save(){ if (DWObject) { DWObject.SaveAllAsPDF("Scanned"); } } function initDWT(){ console.log("initDWT"); const status = document.querySelector(".dwt-status"); Dynamsoft.DWT.Containers = [{ ContainerId: 'dwtcontrolContainer',Width: 270, Height: 350 }]; Dynamsoft.DWT.RegisterEvent('OnWebTwainReady', function () { console.log("ready"); status.innerText = ""; DWObject = Dynamsoft.DWT.GetWebTwain('dwtcontrolContainer'); DWObject.Viewer.width = "100%"; DWObject.Viewer.height = "100%"; DWObject.SetViewMode(2,2); }); status.innerText = "Loading..."; Dynamsoft.DWT.Load(); } function loadLibrary(src,type){ return new Promise(function (resolve, reject) { let scriptEle = document.createElement("script"); scriptEle.setAttribute("type", type); scriptEle.setAttribute("src", src); document.body.appendChild(scriptEle); scriptEle.addEventListener("load", () => { console.log(src+" loaded") resolve(true); }); scriptEle.addEventListener("error", (ev) => { console.log("Error on loading "+src, ev); reject(ev); }); }); }