Optical character recognition can run entirely inside a browser tab. On this site, Image to Text loads the Tesseract.js recognition engine as WebAssembly, reads the picture from local memory and returns editable text, so the image is never transmitted. PDF to Text goes further and usually avoids the recognition engine altogether.
The PDF path is the more interesting design. The tool walks the document page by page and reads any existing text layer first. A digital PDF, one exported from a word processor or a design tool, produces exact text in about a second and never downloads the recognition engine at all. Only pages with essentially no text, which means scans and photographs, are rendered at double size and passed to OCR. That two stage approach means the large download is paid only when it is genuinely needed, and scanned pages are handled one at a time at a few seconds each.
The reason this matters is not abstract. Scanned documents are the category people are least comfortable handing over: signed forms, medical letters, invoices, identity paperwork, anything photographed at a desk. A recognition engine that runs locally removes the decision entirely, because there is no copy to reason about.
Image to Text
Read the text out of a photo, a screenshot or a scan. Multiple images are processed in order, and the result lands in an editable box you can copy or download.
What changes when recognition runs in the browser
A server based OCR service receives your file, runs recognition on its own hardware and returns the text. A browser based tool downloads the engine instead of the document, and the traffic flows in the opposite direction.
| Recognition in the tab | Recognition on a server | |
|---|---|---|
| What crosses the network | Engine and language files, in | Your document, out |
| Copies on someone else's disk | None | At least the upload, usually a result file too |
| Account | Not needed | Often needed for batches or larger files |
| Works offline after first load | Yes | No |
| Speed | A few seconds per scanned page | Faster on heavy batches |
| Verifiable by you | Yes, in the network panel | No |
One technical detail is worth knowing because it explains why this is possible without special server configuration. The engine is single threaded and does not use SharedArrayBuffer, so the page does not need the cross origin isolation headers that multithreaded WebAssembly normally requires. That is why a plain static host can serve it.
The two stage design of PDF to Text
Most PDFs people call scans are not scans at all. A document exported from a word processor, a spreadsheet or a report generator contains real characters, positioned on the page but stored as text. Recognising those characters with OCR would be a strange thing to do, because it introduces errors into data that was already exact.
Stage one: read the text layer
The tool opens the PDF with PDF.js and asks each page for its text content, then rebuilds the reading order from the position data so lines and paragraphs come out in a sensible sequence. This stage is fast and lossless: the characters are the ones the file already contains, so there is nothing to get wrong. A page qualifies as having a text layer when it contains at least 20 non whitespace characters, which is a deliberately low bar so that a page with a genuinely short caption is still read directly.
Stage two: recognise only the pages that need it
Pages that fail that test are the ones that are actually images, and they go through a different route. Each is rendered to a canvas at double the normal size, converted to a PNG and handed to the recognition engine. Doubling the render scale matters more than it sounds, because OCR models work on strokes and edges, and a page rasterised at screen resolution loses the fine detail in small print.
| Document | What the tool does | Engine download |
|---|---|---|
| Digital PDF, all pages have text | Reads the text layer on every page | None |
| Scanned PDF, no text layer | Renders every page at 2x and recognises it | One download, then cached |
| Mixed document, scanned appendix | Reads text pages directly, recognises the rest | One download, used for part of the file |
The result tells you which path each page took. The summary reports the page count, how many pages came from the text layer and how many were recognised, and the body is split into page blocks. That distinction is useful in practice: if a document you expected to be digital reports a pile of recognised pages, it was probably printed to an image somewhere along the way.
PDF to Text
Digital pages are read from the text layer in about a second. The recognition engine is only loaded for pages that are really images.
What the engine actually downloads
Nothing here is fetched when the page loads. The engine arrives on demand, the first time you press the button, and the numbers are worth stating because they explain both the delay and the offline behaviour afterwards.
- The core is about 3.7 MB. That is the WebAssembly build of the recognition model, and it is a single self hosted file rather than several variants.
- English language data is about 2.8 MB and is served from this site, so the common case needs no third party at all. Together the first English run pulls roughly 6.5 MB, and the browser caches it.
- The other languages come from a public Tesseract data CDN. The selector lists twelve languages in total; English is local, and the remaining eleven, from Chinese and Japanese through Russian and Arabic, are downloaded on first use and cached by the engine in IndexedDB.
- One worker is kept at a time. A worker holds the core plus the language data in memory, so switching language terminates the previous one rather than stacking them.
- SIMD support is checked before anything loads. The loader validates a small WebAssembly sample first, because the engine build requires vector instructions. Without that check, an older browser would fail with a low level compilation error instead of a readable message.
How to get a clean result
- Pick the language before you start. It is the single setting that decides accuracy, and it only applies to pages that go through recognition. A digital PDF ignores it entirely.
- Send the sharpest source you have. The original photo beats a screenshot of a preview, and a flat scan beats a phone shot at an angle. If you only have a photo, a slight crop to the text block helps more than any setting.
- Straighten and light it. A page rotated a few degrees, or lit from one side with a shadow across the middle, costs more accuracy than a lower resolution does.
- Run it and read the output. The result box is editable, so fix names and numbers there rather than exporting and patching afterwards.
- Check the confidence figure. It is reported as an average across the file. A low number is a signal to look at the source again, not a verdict on the text.
If a photo needs tidying before recognition, Image Cropper and Image Compressor both run locally, so the whole chain from raw photo to text can stay on the device.
Where OCR still fails
Being clear about this is more useful than a confidence claim, because the failure modes are predictable and they cluster around how the source was produced rather than around the engine.
- Design graphics and coloured backgrounds. The recognition model was trained on documents, not on posters. Tested against this site's own dark blue cover graphic, which has large stylised lettering, the engine returned a single hyphen. Any image where text is decorative rather than typeset is a poor candidate.
- Handwriting. Printed text is the target. Handwritten notes, signatures and form entries produce unreliable output, and no amount of resolution fixes it.
- Poor scans. Faint thermal receipts, faxes, photocopies of photocopies, pages skewed in the scanner. Accuracy falls with each of those, and the tool has no way to warn you which words are doubtful.
- Speed on scanned pages. Recognition takes a few seconds per page, and the work happens on your own CPU, so the tab is busy while it runs. A long scanned document is a slow job rather than an instant one.
- Language coverage. Only the twelve languages in the selector. Anything else is not supported, and a page mixing two scripts is read with the single model you chose, which costs accuracy on the second one.
- Layout is not preserved. The output is plain text with page markers. Columns, tables and sidebars come out as a linear stream, so a complex layout needs reformatting afterwards.
- Password protected PDFs need unlocking first. The reader cannot open an encrypted file, and the tool says so rather than failing silently.
When a server based service is the better answer
Local recognition is the right default for a handful of documents, and it is the wrong tool for a few specific jobs. Three hundred scanned invoices, a handwriting-heavy archive, a script outside the supported list, or a requirement for structured output that preserves table geometry all point the same way, because those need throughput or models that a browser build does not carry.
The useful habit is to separate the two cases before starting. If the document is sensitive and the volume is small, the browser route covers it and the file never moves. If the volume is large, the right move is an approved service rather than a hundred manual runs, and the decision about which service is an organisational one rather than a technical one. That split, and how it applies to teams handling personnel, legal or clinical paperwork, is the subject of sensitive documents and the cloud.