Proyek ini berfungsi sebagai Vite-based compiler / bundler yang mengubah library Node.js server-side ppu-paddle-ocr menjadi modul JavaScript siap pakai di sisi client (web browser).
Pustaka biner bawaan ppu-paddle-ocr memiliki ketergantungan native C++ (seperti OpenCV Node dan ONNX Runtime Node) yang tidak didukung oleh browser. Proyek ini memotong dan mengganti ketergantungan tersebut menggunakan teknik Shimming dan Compile-Time Aliasing.
Modul dikompilasi menggunakan bundler Vite dalam Library Mode dengan konfigurasi alias khusus pada vite.config.js. Berikut adalah detail shim yang disematkan:
- Canvas Shim (
browser-canvas-shim.js): Menangkap impor@napi-rs/canvas(pustaka biner canvas Node) dan mengalihkan seluruh pemanggilan method-method gambarnya ke objek global browser asli (HTMLCanvasElement,document.createElement('canvas'), dannew Image()). Ini memungkinkan pembuatan canvas secara dinamis di dalam browser. - Filesystem Shim (
browser-fs-shim.js): Mengganti pemanggilan sinkron Nodefs.readFileSyncdengan XHR sinkron (XMLHttpRequest) yang dikonfigurasikan denganoverrideMimeType('text/plain; charset=x-user-defined'). Teknik ini memaksa browser mengunduh biner model ONNX sebagai aliran byte raw tanpa merusak struktur filenya, menghindari kesalahan parser browser. - URL-Aware Path Shim (
browser-path-shim.js): Menggantikan parser POSIXpath-browserifydengan wrapper kustom. Ketika mendeteksi URL absolute (http://atauhttps://), modul ini langsung mengembalikan nilainya secara utuh tanpa merusak karakter double-slash (//) menjadi single-slash. - WASM Sequential Engine (
main.js): Menyusun inisialisasi AI secara asinkron (ort.InferenceSession.create(url)). Crucial Browser Optimization: Meng-override methodprocessBoxesInParallelmilikRecognitionServiceagar berjalan secara Sekuensial (satu-demi-satu) dan menambahkan jeda mikrosetTimeout(resolve, 10)sebelum memproses tiap kotak gambar. Ini mencegah runtime WebAssembly (WASM) membekukan / me-lock main thread GUI browser Anda saat memproses puluhan kotak deteksi sekaligus.
Pastikan Anda memiliki Node.js terinstal pada sistem Anda. Masuk ke folder proyek bundler:
cd D:\CraftThingy\client-side-paddle-ocr-projectUnduh Vite beserta pustaka ppu-paddle-ocr asli dari npm registry:
npm installKompilasikan kode sumber beserta seluruh shimming-nya menjadi satu berkas JavaScript tunggal:
npm run buildHasil kompilasi akan ditaruh di folder dist/ dalam format:
dist/paddle-ocr-client.umd.js: Format UMD yang siap diimpor via<script src="...">di HTML/PHP biasa.dist/paddle-ocr-client.es.js: Format ES Modules untuk proyek modern (Vite, Webpack, React, Vue, dll.).
main.js: Titik masuk utama (Entrypoint) yang membungkusPaddleOcrServicemenjadi kelas global browserPaddleOCRClientdan menyematkan patch sekuensial.vite.config.js: Berisi pemetaan alias bundler dan konfigurasi library output.browser-canvas-shim.js: Menjembatani fungsi canvas server ke HTML5 Canvas client.browser-fs-shim.js: Menjembatani fungsifske XMLHttpRequest browser.browser-path-shim.js: Menjembatani fungsi manipulasi direktori ke string URL web.browser-url-shim.js: Menjembatani fungsi pemetaan berkas URL Node.
Pustaka pembungkus (wrapper) utama untuk menjalankan deteksi & rekognisi teks PaddleOCR di dalam browser.
options.verbose(boolean): Menampilkan log debugger di konsol browser (default:false).options.maxSideLength(number): Skala sisi gambar maksimum untuk detektor OCR. Nilai yang lebih tinggi (seperti2000) meningkatkan akurasi deteksi simbol/teks kecil, namun memakan lebih banyak memori (default:2000).
Mengunduh model ONNX dan file dictionary kamus secara asinkron lewat HTTP dan memuatnya ke runtime WebAssembly.
modelConfig.detection(string): URL path file model deteksi ONNX (default:'/models/en_PP-OCRv3_det_infer.onnx').modelConfig.recognition(string): URL path file model rekognisi ONNX (default:'/models/en_PP-OCRv3_rec_infer.onnx').modelConfig.charactersDictionary(string): URL path file kamus karakter (default:'/models/en_dict.txt').
Mengekstrak teks dan koordinat layout geometris dari input gambar/canvas.
imageInput(HTMLImageElement | HTMLCanvasElement | Blob | File | ArrayBuffer): Elemen gambar DOM, elemen canvas, blob file, file lokal, atau buffer biner gambar yang akan dipindai.- Return Value: Mengembalikan
Promiseyang menghasilkan objek:{ "text": "Teks lengkap dokumen hasil gabungan...", "lines": [ { "text": "Baris teks tertentu", "box": { "x": 10, "y": 15, "width": 120, "height": 30 }, "words": [ { "text": "Baris", "box": { "x": 10, "y": 15, "width": 40, "height": 30 } }, { "text": "teks", "box": { "x": 55, "y": 15, "width": 35, "height": 30 } } ] } ] }
<script src="https://cdn.jsdelivr.net/npm/onnxruntime-web@1.20.1/dist/ort.min.js"></script>
<script async src="https://docs.opencv.org/4.5.4/opencv.js"></script>
<script>
window.cv = window.Module = {
onRuntimeInitialized: () => window.isOpencvReady = true
};
window.process = { env: { NODE_ENV: 'production' }, cwd: () => '/' };
window.setImmediate = (fn, ...args) => setTimeout(fn, 0, ...args);
</script>
<script src="/js/paddle-ocr-client.js"></script>
<script>
async function runOCR() {
const ocr = new PaddleOCRClient({ verbose: true });
await ocr.init({
detection: '/models/en_PP-OCRv3_det_infer.onnx',
recognition: '/models/en_PP-OCRv3_rec_infer.onnx',
charactersDictionary: '/models/en_dict.txt'
});
const img = document.getElementById('my-image');
const result = await ocr.recognize(img);
console.log("Hasil pemindaian:", result.text);
}
</script>async function scanPdfPage(pdfUrl, pageNum) {
const loadingTask = pdfjsLib.getDocument(pdfUrl);
const pdfDoc = await loadingTask.promise;
const page = await pdfDoc.getPage(pageNum);
const viewport = page.getViewport({ scale: 1.5 });
const canvas = document.createElement('canvas');
canvas.width = viewport.width;
canvas.height = viewport.height;
const context = canvas.getContext('2d');
await page.render({ canvasContext: context, viewport: viewport }).promise;
const ocr = new PaddleOCRClient();
await ocr.init();
const result = await ocr.recognize(canvas);
console.log(`Teks Halaman ${pageNum}:`, result.text);
}This project serves as a Vite-based compiler / bundler that transforms the server-side Node.js ppu-paddle-ocr library into a client-side JavaScript module ready for web browsers.
Since ppu-paddle-ocr relies on native C++ bindings (such as node-opencv and node-onnxruntime), it cannot run directly in browsers. This project replaces those dependencies using Shimming and Compile-Time Aliasing.
The compiler bundles modules using Vite in Library Mode with custom aliases defined in vite.config.js. Below are the detailed shims applied:
- Canvas Shim (
browser-canvas-shim.js): Reroutes@napi-rs/canvasmethods (a native canvas library for Node) to browser-native canvas elements (HTMLCanvasElement,document.createElement('canvas'), andnew Image()). This allows canvas elements to be created dynamically in the browser. - Filesystem Shim (
browser-fs-shim.js): Replaces Node's synchronousfs.readFileSyncwith a synchronousXMLHttpRequestconfigured withoverrideMimeType('text/plain; charset=x-user-defined')to download raw binary ONNX models without corruption, bypassing browser parser errors. - URL-Aware Path Shim (
browser-path-shim.js): Patches POSIX path helpers to handle absolute URL paths (http://orhttps://) and prevent double-slash (//) paths from being converted into single slashes. - WASM Sequential Engine (
main.js): Sets up asynchronous AI initialization (ort.InferenceSession.create(url)). Crucial Browser Optimization: OverridesprocessBoxesInParallelinsideRecognitionServiceto process bounding boxes sequentially instead of concurrently, yielding withsetTimeout(resolve, 10)before each run. This prevents concurrent WebAssembly inferences from locking up the browser's main GUI thread.
Ensure you have Node.js installed. Navigate to the bundler directory:
cd D:\CraftThingy\client-side-paddle-ocr-projectDownload Vite and the original ppu-paddle-ocr package:
npm installCompile the source code and shims into a single JavaScript library file:
npm run buildThe compiled output is created under the dist/ directory:
dist/paddle-ocr-client.umd.js(Universal Module Definition for script tags in legacy browsers or vanilla HTML/PHP).dist/paddle-ocr-client.es.js(ES Modules for modern bundlers like Vite or Webpack).
main.js: The primary entry point. WrapsPaddleOcrServiceinto a global browser classPaddleOCRClientand hooks the sequential run patch.vite.config.js: Defines the bundler alias mappings and library output config.browser-canvas-shim.js: Redirects canvas operations to HTML5 Canvas.browser-fs-shim.js: Routes Nodefscalls to XMLHttpRequest.browser-path-shim.js: Routes directory manipulation to standard web URLs.browser-url-shim.js: Emulates URL mapping.
The primary library wrapper class to initialize and run PaddleOCR client-side inside the browser.
options.verbose(boolean): Prints debug statements to browser developer tools console (default:false).options.maxSideLength(number): Scaled limit of the maximum side length for the text detector. Larger values (e.g.2000) increase accuracy for small/blurry characters but consume more memory (default:2000).
Asynchronously downloads ONNX model binaries and character files over HTTP and compiles them into WebAssembly.
modelConfig.detection(string): URL path to the detection ONNX model file (default:'/models/en_PP-OCRv3_det_infer.onnx').modelConfig.recognition(string): URL path to the recognition ONNX model file (default:'/models/en_PP-OCRv3_rec_infer.onnx').modelConfig.charactersDictionary(string): URL path to the character dictionary text file (default:'/models/en_dict.txt').
Extracts text boundaries and text lines from a given graphical element.
imageInput(HTMLImageElement | HTMLCanvasElement | Blob | File | ArrayBuffer): The source image/canvas or file binary to scan.- Return Value: Returns a
Promiseresolving to:{ "text": "The compiled string of all recognized text lines...", "lines": [ { "text": "Specific line string content", "box": { "x": 10, "y": 15, "width": 120, "height": 30 }, "words": [ { "text": "Specific", "box": { "x": 10, "y": 15, "width": 40, "height": 30 } }, { "text": "line", "box": { "x": 55, "y": 15, "width": 35, "height": 30 } } ] } ] }
<script src="https://cdn.jsdelivr.net/npm/onnxruntime-web@1.20.1/dist/ort.min.js"></script>
<script async src="https://docs.opencv.org/4.5.4/opencv.js"></script>
<script>
window.cv = window.Module = {
onRuntimeInitialized: () => window.isOpencvReady = true
};
window.process = { env: { NODE_ENV: 'production' }, cwd: () => '/' };
window.setImmediate = (fn, ...args) => setTimeout(fn, 0, ...args);
</script>
<script src="/js/paddle-ocr-client.js"></script>
<script>
async function runOCR() {
const ocr = new PaddleOCRClient({ verbose: true });
await ocr.init({
detection: '/models/en_PP-OCRv3_det_infer.onnx',
recognition: '/models/en_PP-OCRv3_rec_infer.onnx',
charactersDictionary: '/models/en_dict.txt'
});
const img = document.getElementById('my-image');
const result = await ocr.recognize(img);
console.log("Scanned Text Output:", result.text);
}
</script>async function scanPdfPage(pdfUrl, pageNum) {
const loadingTask = pdfjsLib.getDocument(pdfUrl);
const pdfDoc = await loadingTask.promise;
const page = await pdfDoc.getPage(pageNum);
const viewport = page.getViewport({ scale: 1.5 });
const canvas = document.createElement('canvas');
canvas.width = viewport.width;
canvas.height = viewport.height;
const context = canvas.getContext('2d');
await page.render({ canvasContext: context, viewport: viewport }).promise;
const ocr = new PaddleOCRClient();
await ocr.init();
const result = await ocr.recognize(canvas);
console.log(`Page ${pageNum} parsed text:`, result.text);
}Proyek ini dikembangkan oleh CraftThingy Digital Innovation (Alif Nurhidayat). Proyek ini dibangun di atas fondasi inovasi open-source berikut:
- Baidu PaddleOCR: Model deteksi & pengenalan teks kelas dunia yang menjadi inti dari sistem OCR ini.
- ppu-paddle-ocr: Pustaka Node.js yang kami porting, shimming, dan bundle agar dapat berjalan di web browser secara penuh.
- ONNX Runtime Web (Microsoft): Engine eksekusi WebAssembly yang menjalankan model neural network
.onnxdi browser. - OpenCV.js: Pustaka pengolahan citra komputer yang menangani transformasi geometris dan cropping karakter.
- PDF.js (Mozilla): Pustaka rendering dokumen PDF yang memproses halaman dokumen menjadi frame canvas.
This project is developed by CraftThingy Digital Innovation (Alif Nurhidayat). It is built upon the following open-source projects and innovations:
- Baidu PaddleOCR: The world-class OCR system providing the core deep learning models for text detection and recognition.
- ppu-paddle-ocr: The server-side Node.js package which we port, shim, and bundle to run inside browser clients.
- ONNX Runtime Web (Microsoft): The WebAssembly execution runtime that powers the
.onnxmodel inference in browser clients. - OpenCV.js: The computer vision engine handling character cropping and geometry conversions.
- PDF.js (Mozilla): The document rendering library enabling multi-page PDF scanning inside the browser canvas.