Read text off a picture with Tesseract, after preparation that measures the type and enlarges it: 8px text went from a 53 percent character error rate to 8. Every word carries a confidence and a box drawn on the picture.
Related reading
Initializing in your browser…
Convert images to ASCII text art with the ramp measured rather than assumed: each glyph is drawn and its ink counted, the character cell is measured in the font used, and brightness is a named definition.
Turn an image into a data URL whose payload is decoded again and compared byte for byte with the file, with the media type taken from the file's own signature rather than its extension and the size cost of embedding stated in full.
Compare two images with a perceptual engine (pixelmatch) that ignores anti-aliasing, or an exact byte engine. Groups changes into regions with bounding boxes, reports SSIM, and handles size mismatches with an explicit policy.
Ten pages of text this repository drew, in named fonts at named sizes, read back and scored against the string that went in.
Input
the same pangram block at 32, 11 and 8 px, plus inverted, low contrast, blurred, noisy and crooked
Character error rate
before after 32 px (ocr-clean) 0.0% 0.0% 11 px (ocr-small) 3.0% 0.0% 8 px (ocr-tiny) 53.0% 8.3% white on black 0.0% 0.0% 1.9 to 1 contrast 0.0% 0.0% 4 degrees crooked 0.0% 0.0% changing the case a full pass 43 ms word boxes returned 0 23
The reading was already right on eight of the ten, which is worth recording rather than assuming, and it moved the pass to what sits around the decode. Size is what decides an OCR reading: the picture is now measured, and 8 px type is enlarged 3.6 times with Lanczos-3. Turning the preparation off puts it straight back to 53.0 percent. The word boxes were always empty because tesseract.js only returns them when the caller asks for the blocks.
Read the text off a picture in your browser with Tesseract. The page measures your type and enlarges it when it is too small, which is what decides an OCR reading, then shows a box and a confidence for every word it found so you can see what is worth checking.
Get the words out of a picture of an interface, including a dark one.
Photograph or scan a page and read it back, with the doubtful words marked.
Single Line and Sparse Text modes handle the layouts a page mode of Auto struggles with.
White text on near-black is detected as inverted and turned the right way round before reading, and comes back with no character errors.
8 px type is measured at about 4 px of x-height, enlarged 3.6 times, and read at an 8 percent character error rate where it was 53 percent.
Single Line mode with the boxes on: the total is one word with a confidence beside it, so you can see whether to trust it.
The recognition was already right, and measuring it is what settled that. Every fixture here is text this repository DREW, in a font and at a size named in the manifest, so the character error rate is against a string that was chosen rather than found. Against ten such pages the shipped reader was perfect on eight, including one photographed four degrees crooked, a 1.9-to-1 grey-on-grey scan, a 1.2 px blur, plus or minus 40 levels of noise and white-on-black. Recording that is worth as much as finding a fault, because it moved the whole pass to the two cases that did fail and to everything sitting around the decode.
**Size is what decides a reading.** 11 px type read at a 3.0 percent character error rate and 8 px type at 53.0. So the picture is now MEASURED before it is read: the rows of ink are found, the median run gives the body height, and from that an x-height. If it is under the target the page is enlarged with Lanczos-3 (from the resampling module, where each filter carries its paper and is checked against Pillow) and the page says by how much and why. The target is 16 px of x-height rather than the 20 Tesseract's documentation quotes, because 16 is what the measurement said: the 32 px fixture, whose x-height comes to exactly that, already reads with no errors. With preparation on, the 11 px page reads perfectly and the 8 px page drops from 53.0 to 8.3 percent; turn preparation off and it goes straight back to 53.0, which is how you can tell it is the preparation doing the work.
**The tidying is instant.** The case, trim, join and blank-line settings used to be applied INSIDE the extraction, so switching a page to upper case meant running the whole engine again. They are a pure function of the text that came back, so they are re-applied in about 40 milliseconds against a pass measured in seconds, and the raw reading is kept beside the tidied one. Title case leaves an all-capitals word alone, because the naive form turned "ACME Ltd." into "Acme Ltd.". There is also a de-hyphenator for a word split across a line end, which is what a scanned book needs.
**You can see where the words were found.** Tesseract returns a box and a confidence for every word, but only when the caller ASKS for the blocks: without that it returns the text and nothing else, which is why the previous version's word list was always empty and its confidence panel had nothing behind it. The boxes are now drawn over your picture, with anything under 70 percent confidence in red, so a doubtful reading is a place to look rather than a number to worry about. The JSON export carries every box and confidence, the raw reading and what the preparation did.
Beyond that: the engine is kept alive between runs instead of being created and destroyed for each one, a run can be cancelled, a stale run cannot overwrite a newer one, and the HTML export escapes the text, which the previous one did not.
Almost always because it is too small. Measured on this repository's own fixtures, 32 px type reads with no errors, 11 px at 3 percent and 8 px at 53 percent. The preparation measures your type and enlarges it, and the page tells you what it measured.
Tesseract returns a rectangle and a confidence for every word. The boxes are drawn over your picture, and anything under 70 percent is red, which is where a reading is worth a look.
No. The case, trim, join and blank-line settings are applied to the text that came back, so they take about 40 milliseconds. The raw reading is kept, so switching back is free too.
No. Tesseract runs in your browser as WebAssembly, and the language model is downloaded once and cached by the browser.
Less than you would think. A page photographed four degrees off, with a slight blur and noise, read with no character errors at all in the measurement here.
It reduces the page to black and white at Otsu's threshold (1979), which is the standard way to binarise a page without being told where to cut. It helps a stained or unevenly lit scan and is off by default because it can thin out light type.
Images are decoded, edited, and exported entirely inside this browser tab. No originals, exports, or metadata are uploaded.