Maya Chen; the page itself showed nothing.
Before any suggestion can become a black box, we need OCR’s positions to land on exactly the right pixels in the editor.
Checkpoint: redact-05-coordinates, after redact-04-connect-ocr
Two ways to describe a box
OCR and the editor describe the same rectangle in different languages.
The editor uses percentages because the page is drawn at different sizes: big on a monitor, small on a phone, scaled in the safe-share preview.
A mark at
x: 17.5% stays on the same word at any size.
OCR uses pixels because that’s all it knows: the image it was given.
So every box needs converting once, from pixels to percentages, using the size of the exact image OCR read.
That’s why lesson 04’s service refused images whose size didn’t match the request.
Why be so strict about bad boxes?
A wrong outline is worse than no outline. If an outline sits a line too low, a reviewer who trusts it covers the wrong words and shares the real ones. So the conversion fixes what it safely can, like corners given in the wrong order or a box that pokes past the page edge, and throws away what it can’t. More on OCR’s coordinates, including what rotation does to them: OCR boxes and rotation.1. Get this lesson’s code
Stop the app and the service if they’re running. From the repository root,redact-course, bring in this lesson’s commit:
2. Convert one box by hand
The chat image is 1200 pixels wide and 1600 pixels high. In one run, OCR returned this box forMaya Chen:
3. Read the conversion
Opensrc/features/redact/ocr-geometry.ts:
- A page with no size is a bug, so it throws.
- A box with
NaNorInfinityin it is skipped (null). Math.minandMath.maxput the corners in order, whichever way OCR gave them.clamppulls each edge back onto the page.- If nothing is left, because the box had no width or lay entirely off the page, it’s skipped.
- Otherwise it’s converted, using
x2 - x1for the width as you did by hand.
percentage rounds to six decimal places, which is why you get 17.583333 instead of a long fraction.
4. Read where it’s used
InRedactApp.tsx, each OCR block is converted as it arrives:
flatMap with an empty array is how a skipped box disappears.
The block keeps rawBbox too, so you can always see what OCR originally said.
DocumentSurface.tsx then draws one dashed outline per block, positioned with the percentages:
5. Try to break it
Run only these tests:[1300, 1700, -100, -200], and expects the whole page back.
The third checks that NaN, a zero-width box and a box entirely off the page come back as null, and that a page with width 0 throws.
6. See the outlines on the page
Start the service in one terminal and the app in another:public/test-files/redact/chat-private.png, choose Private, and select Prepare for review.
On Original, the header now reads 12 detected regions · drag to draw, and every line of text has a thin dashed outline around it.
Look at Maya Chen: the outline hugs the name.
Now look at Safe-share preview.
Nothing is covered.
Drag across Maya Chen to cover it yourself, and notice your orange mark sits on top of OCR’s dashed outline.
If something goes wrong
- Outlines are offset from the text: the page the browser shows isn’t the image OCR read.
That’s what the size check in lesson 04 prevents; make sure you’re on this lesson’s code with
git log --oneline -1. - No outlines and “Drag to draw · drag marks to move” in the header: no OCR blocks came back, usually because the service isn’t running. The OCR panel on the right will be missing too.
7. Check your work
Stop the app and service, then run:npm test reports Tests 49 passed (49).
So what just happened?
OCR’s pixel boxes now land on the right words in the editor, at any zoom. Boxes that would land in the wrong place are dropped instead of drawn. Every suggestion from here on is tied to one of these outlines.Try it yourself
Pick another block from lesson 02’s output,phone is +1 415 555 0184., and convert its bbox by hand.
Then upload the chat and check your numbers against where its outline sits, on the second line of the first message bubble.
Where to next
- Every file in this checkpoint:
redact/atredact-05-coordinates - About local OCR