// ==UserScript== // @name 识别二维码(Decode QR Code) // @namespace lovefqy/userscripts/decode-qr-code // @version 1.0.0 // @author lovefqy // @description 右键图片识别二维码,支持SVG格式(Right click image recognition QR code, supports SVG format) // @license MIT // @icon data:image/png;base64,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 // @match http*://*/* // @require https://unpkg.com/jsqr@1.4.0/dist/jsQR.js // @grant GM_registerMenuCommand // @grant GM_setClipboard // @run-at context-menu // @noframes // @connect // ==/UserScript== (function (jsQR) { 'use strict'; var _GM_setClipboard = /* @__PURE__ */ (() => typeof GM_setClipboard != "undefined" ? GM_setClipboard : void 0)(); var _GM_registerMenuCommand = /* @__PURE__ */ (() => typeof GM_registerMenuCommand != "undefined" ? GM_registerMenuCommand : void 0)(); let selDomRef = null; function svgToImg(dom,callback){ for(let i=0;i<16;++i){ if (dom instanceof SVGSVGElement){ selDomRef = dom; break } dom=dom.parentElement } const svgContent = new XMLSerializer().serializeToString(dom); var img = new Image(); img.onload = function(e) { callback(e.target) }; img.src = 'data:image/svg+xml;base64,' + btoa(svgContent); } function decodeQrCodeImg(img){ try{ const width = img.width,height=img.height; const canvas = new OffscreenCanvas(width, height); const context = canvas.getContext("2d"); context.drawImage(img, 0, 0); const imageData = context.getImageData(0, 0, width, height); const code= jsQR(imageData.data, width, height) const data = code?.data console.log(data) if(data){ const ok = prompt('点击确定复制二维码(Click OK to copy the QR code)', data) if(ok!=null){ _GM_setClipboard(data, "text"); } }else{ alert('识别失败') } }finally{ selDomRef=null } } _GM_registerMenuCommand("Decode QR Code", () => { if (!selDomRef) { alert('未选择图片') } let dom = selDomRef.deref() if (dom instanceof SVGElement) { svgToImg(dom,decodeQrCodeImg) }else{ decodeQrCodeImg(dom) } }); document.addEventListener("contextmenu", (event) => { let t = event.target if (t instanceof HTMLImageElement) { selDomRef = new WeakRef(t); }else if (t instanceof SVGElement) { for(let i=0;i<16;++i){ if (t instanceof SVGSVGElement){ selDomRef = new WeakRef(t); break } t=t.parentElement } }else selDomRef=null }); })(jsQR);