A test run on 2026-11-06 measured how small Chinese text can get before OCR gives up, and the strangest row came from the control, not the main experiment. The main experiment rendered one paragraph at different text heights and counted wrong characters. The control took the 8 px image exactly as it was and pasted it into the top-left corner of a 1200×1200 white canvas. No scaling, no resampling, the letters keep every pixel they had, there is just a lot more white around them. macOS built-in text recognition went from 88.0% to 0% on that image. It did not return garbled text. It returned nothing.
What was actually tested
All samples are self-made and very clean, so please read this as one data point. The Chinese sample is a 275-character notice text, rendered black on white, single column, one font per image: Songti, a serif with thin horizontal strokes, and Heiti, a sans with even strokes. "Text height" here means the pixel height of the ink bounding box of the character 国, and for the English control it is the height of a capital H in a 452-character paragraph. The machine is an Apple M4 Mac, and every number is a single run. With only 275 characters, one wrong character already costs 0.36%, so small differences are noise. The macOS side is the Vision framework in accurate mode. Tesseract 5.5.3 only ran on English because there was no Chinese language pack installed. The browser recognizer is the image text recognition in ImgIng https://imging.ai/ , run in a desktop browser. Below I just call it the browser recognizer. Every number in this post is measured in this test, and anything about why it happens is my inference.
The numbers
| Recognizer and sample | Original image | Pasted on 1200×1200 |
|---|---|---|
| macOS Vision, Heiti 8 px | 88.0% (33 wrong) | 0% (275 wrong, empty output) |
| macOS Vision, Songti 8 px | 92.0% (22 wrong) | 68.4% (87 wrong) |
| macOS Vision, Heiti 6 px / Songti 6 px | 6.9% / 1.8% | 0% / 0% |
| macOS Vision, English 8 px | 99.34% | 99.34% |
| Browser recognizer, Heiti 6 px | 95.3% | 80.0% |
| Browser recognizer, Heiti 8 px | 98.6% | 97.5% |
| Browser recognizer, Songti 6 px / 8 px | 71.3% / 97.8% | 63.6% / 98.6% |
| Tesseract, English 6 px / 8 px | 16.8% / 95.4% | 20.8% / 95.4% |
The Heiti 8 px row is the odd one. 33 wrong out of 275 on the original, then 275 wrong, which is every character, because the output was empty. Songti 8 px lost less and landed at 68.4%. At 6 px Vision was already close to useless on the original image and simply went to zero on the canvas. For context, the same recognizer read the same paragraph rendered at 12 px with 1 wrong character in Songti and 0 in Heiti, so this is not a recognizer that is bad at Chinese in general.
Not every recognizer cared about the canvas
Tesseract on English barely moved, and 8 px stayed at 95.4% on both sides. The browser recognizer dropped too, but by a lot less, and its Songti 8 px even came out slightly higher on the big canvas. The row that doesn't fit is Vision on English 8 px, which read 99.34% before and 99.34% after. Same recognizer, same text height, same canvas size, and only the Chinese collapsed.
My guess, labeled as a guess
The measurement covers the phenomenon. The cause is inference. My best guess is that Vision scales the whole image down to some internal working size before recognizing anything, which would make the relevant number the text height relative to the whole image, not the absolute pixel height. An 8 px character in a small image would survive that step, while the same character inside 1200×1200 would get squeezed below what it needs. That is not verified. Only the 6 and 8 px levels were tested on the big canvas, only at the top-left position and only at one canvas size. The English row doesn't fit neatly either: maybe dense Chinese strokes break first when everything shrinks, or maybe the guess is just wrong.
What to try with a big screenshot
The practical side is also inference, supported only by this one control. If small Chinese text sits inside a large image, cropping the text region out before sending it to Vision is the cheapest thing to try, since it adds no new pixels. Upscaling is a separate question with its own numbers from the same test. A bilinear upscale of the original small images to about 32 px took Vision's Heiti 6 px from 256 wrong characters to 37, but Songti 6 px got to 53.1% at best, far from the 99.64% it scores on a native 12 px render. So in this sample, upscaling afterwards never caught up with text rendered larger in the first place, which is why a fresh screenshot at a higher device pixel ratio is worth trying before any resize. A safer order is to crop first, estimate the text height, and only then decide whether upscaling is worth it, and to compare the output once instead of assuming bigger is better.
Limits worth repeating: white background, black text, one font, no compression and no noise, so real screenshots may do worse at the same text height, which is also a guess. The crop fix itself was not tested directly. If a Vision pipeline returns empty strings for screenshots that look perfectly readable, compare the text height with the full image size before touching the language settings.


![AMR AI and Embodied Intelligence — Ch.18: GPU and Accelerator Design [KR]](https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fospxyzadkcmpo8xjqyok.png)