Bitonal TIFF, before the upload.
One call turns a scan, an image or PDF in any common format, into a clean 1-bpp black & white TIFF, the format OCR engines expect. It runs in the browser on the user's own device, so the document is already prepared before you decide whether to send it anywhere.
One method. One bitonal TIFF.
Feed ocrbw() a scan in any common format, JPEG, PNG, TIFF or PDF, and you get back a 1-bpp black & white TIFF, every pixel either black or white, one bit each. That is the shape most OCR engines want to be handed, and computing it on the client means the raw scan does not have to travel first.
- ✓ Input: one image or PDF, JPEG, PNG, TIFF and other common formats, as a
Uint8Array - ✓ Output:
DATA, a 1-bpp BW TIFF as aUint8Array - ✓ Runs entirely in WebAssembly on the user's device
- ✓ Same method name in both run modes
- ✓ Returns
{ STATUS, DESCRIPTION, DATA }, never throws - ✓ No server round-trip, so it works offline
// Everything below runs on this device. const helper = new ImageWizHelper(); await helper.ready; await helper.initialize(LICENSE_BLOB); const file = input.files[0]; const buf = new Uint8Array(await file.arrayBuffer()); const res = await helper.ocrbw(buf); if (res.STATUS) { // res.DATA → Uint8Array, a 1-bpp BW TIFF const blob = new Blob([res.DATA], { type: 'image/tiff' }); body.append('file', blob, 'clean.tiff'); // → your OCR } else { console.error(res.DESCRIPTION); // no throw }
Where cleanup belongs
Cleanup is the step between capture and recognition. Doing it in the browser means the bytes you eventually send are bitonal, and the bytes you don't send never left.
Uint8Array.readImageInformation() for page count, dimensions, DPI and colour type before you commit.ocrbw() returns the 1-bpp BW TIFF. No upload has happened yet.The privacy line moves
The SDK is WebAssembly running in the page. A document is only ever transmitted if your own code chooses to transmit it after cleanup, the cleanup step itself has no network dependency, which is also why it keeps working with no connection at all.
Three practical consequences
The scan stays put
Cleanup happens on the user's device. Nothing is uploaded to produce the bitonal TIFF, so the original never crosses your network boundary unless you send it deliberately.
One bit per pixel
The output is a 1-bpp black & white TIFF: each pixel carries a single bit rather than a colour value. It is the representation OCR engines are built to consume.
Two run modes
Load the main-thread build for the simplest path, or the worker-pool build to keep the UI responsive and fan a batch out in parallel. Identical method names either way.
A batch, off the main thread
The worker-pool build spreads one task per file across the pool, so a folder of scans cleans up without freezing the page.
const helper = new ImageWizHelper(); // worker pool await helper.ready; await helper.initialize(LICENSE_BLOB); const buffers = await Promise.all( [...input.files].map(async f => new Uint8Array(await f.arrayBuffer())) ); // one task per file, fanned out across the pool const results = await Promise.all( buffers.map(b => helper.ocrbw(b)) ); results.forEach((r, i) => { if (r.STATUS) save(`clean_${i}.tiff`, r.DATA); else console.warn(i, r.DESCRIPTION); });
// Confirm what you're about to send. const info = await helper.readImageInformation(r.DATA); if (info.STATUS) { console.log(info.DATA.TOTAL_PAGES); // page count console.log(info.DATA.FILESIZE); // KB info.DATA.INFORMATION.forEach(p => { console.log( p.PAGE_NO, p.WIDTH, p.HEIGHT, p.DPI, p.COLOR_TYPE // "BW" ); }); }
One gotcha worth knowing
The worker facade transfers input ArrayBuffers into the worker, which detaches them on the caller's side. If you need the original bytes again after the call, re-read the file.
Questions, answered plainly
{ STATUS, DESCRIPTION, DATA }. On success STATUS is true, DESCRIPTION is "SUCCESS", and DATA is a Uint8Array holding a 1-bpp black & white TIFF. Failures come back through STATUS and DESCRIPTION, the API does not throw.SetFilter(200) followed by compressToTiff(buffers) applies a black-and-white filter per page and takes an array of inputs, producing one multi-page TIFF. ocrbw(buffer) takes a single image or PDF and is the method documented to return a 1-bpp BW TIFF.initialize() is non-fatal. With a missing or rejected licence blob the SDK still initializes and every operation still works, the output is simply watermarked while it runs in demo state. That makes it straightforward to evaluate before you talk to us about licensing.readImageInformation(). It returns FILESIZE in KB, TOTAL_PAGES, and a per-page INFORMATION array carrying WIDTH, HEIGHT, DPI and COLOR_TYPE, the last of which reads "BW", "GREYSCALE" or "COLOR".file:// page will not load the .wasm. Keep the distributed files together in one directory, since the loader resolves its siblings relative to its own script URL. After that, no connection is needed for cleanup itself.