Skip to content

Commit 5583327

Browse files
committed
init: 🎉 添加图片二维码识别脚本
1 parent f0cc1a3 commit 5583327

10 files changed

Lines changed: 197 additions & 1 deletion

File tree

.vscode/settings.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,19 @@
8989
"antfu",
9090
"bili",
9191
"bilibili",
92+
"binarize",
93+
"binarized",
9294
"breakline",
9395
"commitlint",
9496
"contenteditable",
9597
"dede",
98+
"jsqr",
9699
"labelledby",
100+
"notiflix",
101+
"nuintun",
97102
"onurlchange",
98103
"prefixs",
104+
"qrcode",
99105
"radash",
100106
"swal",
101107
"sweetalert",
@@ -112,6 +118,7 @@
112118
],
113119
"cSpell.ignorePaths": [
114120
"*.yaml",
115-
"*.vscode"
121+
"*.vscode",
122+
"dist/*.user.js"
116123
]
117124
}

apps/common/qr-code/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# common-qr-code
2+
3+
## 1.0.0
4+
5+
### Major Changes
6+
7+
- init

apps/common/qr-code/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# 图片二维码识别(Common QR Code)
2+
3+
**右键图片,识别二维码并复制到剪贴板。**
4+
5+
## 📋 更新日志
6+
7+
[CHANGELOG](https://github.com/xiaohuohumax/userscripts/blob/main/apps/common/qr-code/CHANGELOG.md)
8+
9+
## 📖 使用方式
10+
11+
![](https://raw.githubusercontent.com/xiaohuohumax/userscripts/main/apps/common/qr-code/images/use.gif)

apps/common/qr-code/images/use.gif

314 KB
Loading

apps/common/qr-code/package.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "common-qr-code",
3+
"type": "module",
4+
"version": "1.0.0",
5+
"private": true,
6+
"description": "图片二维码识别(Common QR Code)-- 右键图片,识别二维码并复制到剪贴板。",
7+
"author": {
8+
"name": "xiaohuohumax",
9+
"url": "https://github.com/xiaohuohumax"
10+
},
11+
"license": "MIT",
12+
"repository": {
13+
"type": "git",
14+
"url": "https://github.com/xiaohuohumax/userscripts.git"
15+
},
16+
"keywords": [
17+
"typescript",
18+
"tampermonkey",
19+
"common",
20+
"qr-code"
21+
],
22+
"scripts": {
23+
"dev": "vite",
24+
"build": "vite build --emptyOutDir=false"
25+
},
26+
"dependencies": {
27+
"jsqr": "^1.4.0",
28+
"notiflix": "^3.2.8"
29+
},
30+
"devDependencies": {
31+
"vite-plugin-meta": "workspace:^"
32+
}
33+
}

apps/common/qr-code/src/index.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { GM_registerMenuCommand, GM_setClipboard } from '$'
2+
import { Notify } from 'notiflix/build/notiflix-notify-aio'
3+
import { ID, VERSION } from 'virtual:meta'
4+
5+
import { decodeQrCode } from './utils'
6+
7+
console.log(`${ID}(v${VERSION})`)
8+
9+
let image: HTMLImageElement | null = null
10+
11+
GM_registerMenuCommand('Decode QR Code', () => {
12+
if (!image) {
13+
return Notify.warning('未选择图片, 请先右键选择图片')
14+
}
15+
decodeQrCode(image.src).then((data) => {
16+
if (data === undefined) {
17+
return Notify.warning('未识别到二维码, 请确认图片是否有效')
18+
}
19+
Notify.success('识别成功, 已复制到剪贴板')
20+
GM_setClipboard(data, 'text')
21+
}).catch((error) => {
22+
Notify.failure('识别失败, 请检查图片是否有效')
23+
console.error(error)
24+
}).finally(() => (image = null))
25+
})
26+
27+
document.addEventListener('contextmenu', (event) => {
28+
if (event.target instanceof HTMLImageElement) {
29+
image = event.target
30+
}
31+
})

apps/common/qr-code/src/utils.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { GM_xmlhttpRequest } from '$'
2+
3+
import jsQR from 'jsqr'
4+
5+
export async function decodeQrCode(url: string): Promise<string | undefined> {
6+
return new Promise((resolve, reject) => {
7+
const image = new Image()
8+
9+
image.onload = () => {
10+
const { width, height } = image
11+
const canvas = new OffscreenCanvas(width, height)
12+
const context = canvas.getContext('2d')!
13+
context.drawImage(image, 0, 0)
14+
const imageData = context.getImageData(0, 0, width, height)
15+
resolve(jsQR(imageData.data, width, height)?.data.replace(/^\s+|\s+$/g, ''))
16+
}
17+
18+
image.onerror = reject
19+
20+
GM_xmlhttpRequest({
21+
method: 'GET',
22+
url,
23+
anonymous: true,
24+
responseType: 'blob',
25+
onload: (response) => {
26+
if (response.status !== 200) {
27+
reject(new Error(`Failed to load image: ${response.status} ${response.statusText}`))
28+
return
29+
}
30+
image.src = URL.createObjectURL(response.response)
31+
},
32+
onerror: reject,
33+
})
34+
})
35+
}

apps/common/qr-code/tsconfig.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"extends": "../../../tsconfig.base.json",
3+
"compilerOptions": {
4+
"types": [
5+
"vite/client",
6+
"vite-plugin-monkey/client",
7+
"vite-plugin-meta/client"
8+
]
9+
},
10+
"include": [
11+
"src",
12+
"*.d.ts"
13+
]
14+
}

apps/common/qr-code/vite.config.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { defineConfig } from 'vite'
2+
import meta from 'vite-plugin-meta'
3+
import monkey, { cdn } from 'vite-plugin-monkey'
4+
5+
export default defineConfig({
6+
build: {
7+
outDir: '../../../dist/',
8+
},
9+
plugins: [
10+
meta(),
11+
monkey({
12+
entry: 'src/index.ts',
13+
build: {
14+
externalGlobals: {
15+
'jsqr': cdn.unpkg('jsQR', 'dist/jsQR.js'),
16+
'notiflix/build/notiflix-notify-aio': cdn.unpkg('Notiflix', 'build/notiflix-notify-aio.js'),
17+
},
18+
},
19+
userscript: {
20+
'name': '图片二维码识别(Common QR Code)',
21+
'description': '右键图片,识别二维码并复制到剪贴板。',
22+
'icon': 'https://raw.githubusercontent.com/xiaohuohumax/logo/refs/heads/main/logos/logo.svg',
23+
'namespace': 'xiaohuohumax/userscripts/common-qr-code',
24+
'license': 'MIT',
25+
'updateURL': 'https://raw.githubusercontent.com/xiaohuohumax/userscripts/main/dist/common-qr-code.user.js',
26+
'downloadURL': 'https://raw.githubusercontent.com/xiaohuohumax/userscripts/main/dist/common-qr-code.user.js',
27+
'noframes': true,
28+
'run-at': 'document-start',
29+
'match': [
30+
'http*://*/*',
31+
],
32+
},
33+
}),
34+
],
35+
})

pnpm-lock.yaml

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)