Blog

How to tell if a PDF is real text or a photo of text

Two PDFs can look identical and be completely different files. Here is the three second test, the one that scales, and the case that fools both.

Try to select a line with your cursor. If a neat blue highlight follows the words, the file contains real text. If the selection jumps to a rectangle covering the whole page, or nothing highlights at all, you are looking at a photograph of a document and there is no text in it to find. That test takes three seconds and it decides what every tool you point at the file is capable of doing.

Why two identical-looking files behave completely differently

A PDF can hold text two ways.

Born digital. Something exported the file from Word, InDesign, LaTeX or a reporting system. The characters are in the file as characters, positioned on the page. A tool can read them.

Scanned. Someone put paper through a scanner or photographed it with a phone. The file contains one large image per page. To your eye it is a document. To any program, it is a picture, and it contains exactly as much text as a photograph of a road sign does.

Both open in the same viewer, print the same, and are the same file format. Nothing on screen distinguishes them. But a scanned PDF cannot be searched, cannot be read aloud by a screen reader, cannot be copied from, and cannot be extracted for a language model, because in every one of those cases the thing being asked for does not exist in the file.

The test that scales

The cursor test is fine for one file. For a folder of four thousand, you want a number.

The approach is the same either way: extract the text and see how much comes out. A real text page produces hundreds or thousands of characters. A scanned page produces almost nothing, usually zero, sometimes a stray character or two from a stamp or a watermark that was added digitally after scanning.

On the command line, Poppler’s pdftotext is the usual tool:

pdftotext -l 5 report.pdf - | wc -c

That extracts the first five pages and counts the characters. A few thousand means real text. Under a hundred means you are almost certainly looking at images.

Two things to be careful about if you turn this into a script.

Sample several pages, not one. The first page of a report is often a designed cover, and covers are frequently images even in born digital documents. Checking pages three to seven tells you more about the document than checking page one.

Pick your own threshold and look at the results. Any cutoff you choose will be arbitrary, so run it over a sample, sort the borderline files, and open a few. It takes ten minutes and it stops you from silently misclassifying a whole category of document, which is the failure mode that actually costs you.

The case that fools both tests

Here is where it gets interesting, and where most guides stop.

A scanned PDF can have text added to it afterwards. Scanning software, and many document management systems, run optical character recognition over the image and store the recognised words underneath it, invisibly, in roughly the right positions. The result is called a searchable PDF, and it is genuinely useful: the file is now searchable and selectable, even though what you see is still the photograph.

So a searchable PDF passes both tests above. The cursor selects text. pdftotext returns thousands of characters. It looks born digital.

The difference is that the text is a machine’s best guess rather than a record of what was typed, and the quality of that guess is invisible in the file. Poor scans produce text with confident, plausible errors: “rn” read as “m”, “1” read as “l”, a whole column dropped because the page was slightly rotated, a table read out in the wrong order. Nothing marks any of it as uncertain.

For search this is mostly fine, because a few wrong characters cost you a few hits. For feeding a model it is worse, because the model has no way to know which words were recognised confidently and which were guessed, and it will treat a misread figure with exactly the same confidence as a correct one.

How to spot it: copy a paragraph out and read it. Real text is either right or obviously broken. OCR text has a specific texture: mostly correct, with occasional words that are not words, inconsistent spacing, and numbers that look slightly off. Also check whether the text you select lines up exactly with the glyphs on screen. In a searchable PDF the invisible layer is positioned approximately, so the highlight often sits a little askew.

The other clue is file size. A born digital report of forty pages is usually well under a megabyte, because it stores characters and font references. A scan of the same document is often tens of megabytes, because it stores forty photographs. If a text document is unexpectedly enormous, it is probably images.

Mixed documents, which are more common than you would think

Real document sets are rarely all one or the other. The pattern that catches people is the file that is mostly born digital with a handful of scanned pages inserted: a signed signature page, an appendix that came in by fax, a certificate.

A per-file check marks that document as real text, because most of its pages are. The scanned pages then pass silently into your pipeline as empty, and the content on them is simply absent from your index. Nobody notices, because nothing failed.

If you are building anything that depends on completeness, check per page rather than per file, and record which pages produced no text. That list is worth having.

Why it matters, in four directions

Search. A scanned document is invisible to search. Not ranked low: absent. A public body with four thousand scanned PDFs has four thousand documents nobody can find.

Accessibility. A screen reader reads text. Given an image of a page, it has nothing to announce, so the document is not just hard to use, it is unusable. This is now a legal exposure in a growing number of places rather than only a courtesy, and scanned documents are the single largest category of inaccessible public document.

AI extraction. Every retrieval or summarisation pipeline starts by extracting text. Point one at a scanned file and it gets an empty string, which usually does not raise an error. The document is then in your system with no content, and the failure surfaces much later as an answer that does not mention something it should have.

File size. Scans are large, and they are large per page, so they are the reason document stores balloon.

What to do about it

If the file is real text, nothing. Convert it and go.

If it is scanned, you need optical character recognition before anything else can happen. Tesseract is the long-standing open source engine and is what most free tools use underneath. Commercial services are meaningfully more accurate on poor scans, which is worth paying for if the documents matter. Whichever you use, the output is a guess, so keep the original image alongside the recognised text rather than discarding it, and keep a way to show a human the page when the text is disputed.

If it is a searchable PDF, decide whether the existing OCR layer is good enough before you build on it. Read a page of the extracted text. If it is clean, use it. If it is full of small errors, re-running recognition with a better engine is usually cheaper than dealing with the errors downstream forever.

If you are not sure which you have, our PDF to Markdown converter will tell you. It reads text rather than pictures, so when there is nothing to read it says so and names OCR as the fix, instead of handing back an empty file and letting you discover the problem three steps later. It runs in your browser, so you can check a document you are not free to upload anywhere.

Where this leads

If your documents are scans, the whole extraction-first approach described in what a good PDF conversion keeps is the wrong tool, and no amount of layout inference will help. That is worth knowing early rather than after you have built a pipeline around it.

And if they are real text, this test rules out the one failure that is obvious, which leaves the four that are not. Those are the ones that quietly degrade retrieval without ever raising an error.

The short version

  • Try to select a line. Neat highlight means real text. Whole-page rectangle means an image.
  • At scale, extract text and count characters, sampling several pages rather than the cover.
  • A searchable PDF passes both tests and is still a scan underneath. The text is a machine’s guess and its errors are invisible.
  • Check per page, not per file. Mixed documents with a few scanned pages are common and those pages vanish silently.
  • Scanned means unsearchable, inaccessible, unextractable and large. It needs OCR before anything else is possible.

Further reading

  • Web Content Accessibility Guidelines, W3C. The reference standard behind most legal accessibility requirements, and the reason a page of images is a compliance problem rather than an inconvenience.
  • Tesseract, the open source OCR engine maintained since 2006. Its documentation is unusually honest about the conditions under which recognition quality falls apart.
  • Poppler, the library behind pdftotext and much of the Linux PDF tooling. The quickest way to run the character-count test over a large document set.
  • ISO 32000-1, the PDF specification. Clause 8 covers graphics and images, clause 9 covers text. Reading them side by side makes it obvious why one file can contain either and look the same.