DEV Community

NullPointerZen
NullPointerZen

Posted on

Getting the text out of five screenshots inside one PDF

The document is a three-page weekly ops report with five screenshots pasted in: a growth dashboard, a chat channel, a spreadsheet, an alert and a kanban board. I built it myself as a test file with invented content, because it's such a common shape of document: someone screenshots five tools and drops them into a report, and later someone else needs the words.

Select-all and copy doesn't get you there. Pulling the text layer out with pypdf gives 20 lines: the body paragraphs, the five captions, and a header and footer on each page. Not a single word from inside a screenshot, because to the PDF those are just pictures.

For one screenshot I'd use what the operating system already has, Live Text on a Mac or Text Actions in the Windows Snipping Tool: open the page, grab the image, copy. Five screenshots over three pages is where that gets old. So I dropped the whole PDF into ImgIng's Extract PDF content, left "Recognize text inside images" ticked, kept the OCR model on "Auto · recommended" and pressed Start. No account, and the workspace says the file is read only in the browser and never uploaded.

What came back

All five screenshots were read in one run. Each becomes a block labelled Image OCR, placed right after its screenshot and before the caption, in page order. In the TXT export the label is [Image OCR], and in Markdown it's a bold Image OCR line followed by a text code block. The four dashboard tiles came out perfectly and lined up with Tabs: the labels, then 12,480 3.2% $41.70 1.8%, then the deltas. The chat came through with all four messages, right text, right speaker, except that Leo Park's name got glued to his timestamp both times (Leo Park14:09) while Maya Chen's didn't. The spreadsheet was the best part: six rows, four columns, every cell right and Tab-separated, so it pastes straight into a sheet. The alert's five lines were right too, with the title losing the spaces around its dot (Alert·payments-api).

Two screenshots didn't go as well. The bar chart under the dashboard tiles has seven values, one per day. The OCR kept every number but grouped them by bar height into two rows, 342 355 372 360 and 310 295 _ _ 180 _, so which number is Monday's you can only tell from the picture.

English Extract PDF content workspace: the dashboard's bar chart (boxed in the result pane) and its OCR text, where

On the kanban board, the three column names and three of the four cards were right. The fourth card, OPS-416, came back as just its ID. Its title, "Retry budget per client", is nowhere in the output, and nothing marks it as missing.

The kanban screenshot with the OPS-416 card boxed, and the Image OCR block below it ending in a bare

One more thing went missing, and this one I can't explain. Each page of the report has a small header ("Ops Weekly Report · Week 36, 2026") and a footer ("1 / 3" and so on). None of those six lines appear in the TXT, Markdown or HTML. My guess is that text repeated identically on every page gets treated as furniture and dropped, but that's a guess; a two-column test file I made kept its headers and footers. For a weekly report I'd strip them anyway. If your header carries the only copy of the date, keep an eye on it.

Checking without rereading everything

Since every recognised block is labelled, I only reread those, side by side with their screenshots, and I always take chart numbers from the image. Before rereading anything, though, I make a quick overview: for each Image OCR block in the TXT export, I note which caption follows it, how many lines it has, and what its very last line says. You can do this by searching for the label and scrolling, or with a few lines of script if you do this often. On this report the overview was five short rows. The dashboard block had 7 lines and ended on the weekday row. The chat had 9 lines and ended mid-sentence on the closing message about the error rate. The sheet had 7 lines ending on its Total row, the alert had 6 ending on the runbook line, and the ops board had 5 lines ending on a bare "OPS-416".

The last line turns out to be a decent tell. A normal block ends on a sentence, a totals row or a label, because that's how the screenshot itself ends. A block that ends on a bare ticket number is a card whose text got cut, and that's how OPS-416 jumped out before I'd read any of the other 33 lines. It won't catch the bar chart, which ends on a perfectly normal row of weekdays, so the numbers above it look fine until you compare them with the bars; charts I just check by eye every time.

So my routine is short: one screenshot, the OS's own text grab; several screenshots, the whole file in one pass, then straight to the Image OCR blocks. The extractor is at https://imging.ai/

Top comments (0)