add janky image OCR

This commit is contained in:
catto 2024-04-19 23:50:33 +02:00
parent 4f86f26972
commit 75eb5301fd
4 changed files with 143 additions and 5 deletions

View File

@ -28,6 +28,8 @@
<button class="row" id="show-notes-button">Refresh Notes</button> <button class="row" id="show-notes-button">Refresh Notes</button>
<button type="submit" id="save-button">Save</button> <button type="submit" id="save-button">Save</button>
<button class="row" id="new-button">New</button> <button class="row" id="new-button">New</button>
<button class="row" id="image-button">OCR</button>
<input type="file" id="fileInput" accept="image/*" style="display: none;" />
</div> </div>
</div> </div>
<div class="container"> <div class="container">

110
package-lock.json generated
View File

@ -8,7 +8,8 @@
"name": "snotes-deck", "name": "snotes-deck",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@tauri-apps/api": "^1" "@tauri-apps/api": "^1",
"tesseract.js": "^5.0.5"
}, },
"devDependencies": { "devDependencies": {
"@tauri-apps/cli": "^1", "@tauri-apps/cli": "^1",
@ -787,6 +788,11 @@
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"dev": true "dev": true
}, },
"node_modules/bmp-js": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz",
"integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw=="
},
"node_modules/esbuild": { "node_modules/esbuild": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
@ -839,6 +845,21 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0" "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
} }
}, },
"node_modules/idb-keyval": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.1.tgz",
"integrity": "sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg=="
},
"node_modules/is-electron": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.2.2.tgz",
"integrity": "sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg=="
},
"node_modules/is-url": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
"integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww=="
},
"node_modules/nanoid": { "node_modules/nanoid": {
"version": "3.3.7", "version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
@ -857,6 +878,33 @@
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
} }
}, },
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/opencollective-postinstall": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
"integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
"bin": {
"opencollective-postinstall": "index.js"
}
},
"node_modules/picocolors": { "node_modules/picocolors": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
@ -891,6 +939,11 @@
"node": "^10 || ^12 || >=14" "node": "^10 || ^12 || >=14"
} }
}, },
"node_modules/regenerator-runtime": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
},
"node_modules/rollup": { "node_modules/rollup": {
"version": "4.14.1", "version": "4.14.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.1.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.1.tgz",
@ -934,6 +987,34 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/tesseract.js": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/tesseract.js/-/tesseract.js-5.0.5.tgz",
"integrity": "sha512-xtTfec4IynE63sl6kAFkGl1mejlNxr9qQXzVGAUHd7IPdQXveopjGO9Eph6xkSuW5sUCC9AT6VdBmODh8ZymGg==",
"hasInstallScript": true,
"dependencies": {
"bmp-js": "^0.1.0",
"idb-keyval": "^6.2.0",
"is-electron": "^2.2.2",
"is-url": "^1.2.4",
"node-fetch": "^2.6.9",
"opencollective-postinstall": "^2.0.3",
"regenerator-runtime": "^0.13.3",
"tesseract.js-core": "^5.0.0",
"wasm-feature-detect": "^1.2.11",
"zlibjs": "^0.3.1"
}
},
"node_modules/tesseract.js-core": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/tesseract.js-core/-/tesseract.js-core-5.1.0.tgz",
"integrity": "sha512-D4gc5ET1DF/sDayF/eVmHgVGo7nqVC2e3d7uVgVOSAk4NOcmUqvJRTj8etqEmI/2390ZkXCRiDMxTD1RFYyp1g=="
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
},
"node_modules/typescript": { "node_modules/typescript": {
"version": "5.4.4", "version": "5.4.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz",
@ -1001,6 +1082,33 @@
"optional": true "optional": true
} }
} }
},
"node_modules/wasm-feature-detect": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/wasm-feature-detect/-/wasm-feature-detect-1.6.1.tgz",
"integrity": "sha512-R1i9ED8UlLu/foILNB1ck9XS63vdtqU/tP1MCugVekETp/ySCrBZRk5I/zI67cI1wlQYeSonNm1PLjDHZDNg6g=="
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/zlibjs": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/zlibjs/-/zlibjs-0.3.1.tgz",
"integrity": "sha512-+J9RrgTKOmlxFSDHo0pI1xM6BLVUv+o0ZT9ANtCxGkjIVCCUdx9alUF8Gm+dGLKbkkkidWIHFDZHDMpfITt4+w==",
"engines": {
"node": "*"
}
} }
} }
} }

View File

@ -10,11 +10,12 @@
"tauri": "tauri" "tauri": "tauri"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "^1" "@tauri-apps/api": "^1",
"tesseract.js": "^5.0.5"
}, },
"devDependencies": { "devDependencies": {
"@tauri-apps/cli": "^1", "@tauri-apps/cli": "^1",
"vite": "^5.0.0", "typescript": "^5.0.2",
"typescript": "^5.0.2" "vite": "^5.0.0"
} }
} }

View File

@ -1,6 +1,6 @@
import { invoke } from "@tauri-apps/api/tauri"; import { invoke } from "@tauri-apps/api/tauri";
import { Note, Settings } from "./model"; import { Note, Settings } from "./model";
import { createWorker } from 'tesseract.js';
let notesMsgEl: HTMLElement | null; let notesMsgEl: HTMLElement | null;
@ -197,6 +197,33 @@ window.addEventListener("DOMContentLoaded", async () => {
createNoteContentEl.style.fontSize = settings.fontSize createNoteContentEl.style.fontSize = settings.fontSize
} }
// OCR
const uploadOcrImageButtonEl = document.getElementById('image-button') as HTMLButtonElement;
const ocrFileInputEl = document.getElementById('fileInput') as HTMLInputElement;
uploadOcrImageButtonEl.addEventListener('click', () => {
ocrFileInputEl.click(); // Simulate click on the file input
});
ocrFileInputEl.addEventListener('change', (event) => {
const files = (event.target as HTMLInputElement).files;
if (files) {
console.log('Selected file:', files[0].name);
ocrFileInputEl.src = URL.createObjectURL(files[0]);
(async () => {
// TODO: change ocr language in settings
const worker = await createWorker('eng');
const ret = await worker.recognize(files[0]);
console.log(ret.data.text);
if (createNoteContentEl) [
createNoteContentEl.value += ret.data.text
]
await worker.terminate();
})();
}
});
refreshContextMenuElements(); refreshContextMenuElements();
}); });