Why PDF compression quietly turns your text into a picture
A 6-page text PDF went from 298.7 KB to 8.9 KB with every one of its 26,652 characters still selectable. The usual way to shrink a PDF gets to 30.5 KB and zero. There are two ways to make a PDF smaller. Only one of them keeps the document a document. The common way is to render every page to an image and rebuild the file from those images. It always works, it works on scanned documents, and it is…
PDF compression can silently transform text into a picture without the user noticing. A 6-page text PDF can shrink from 298.7 KB to just 8.9 KB while preserving all 26,652 selectable characters. There are two main methods to reduce PDF size: converting it to an image or optimizing the file without turning it into an image. However, the former method always works, even on scanned documents, but it converts the document into a photograph of words.
The latter approach preserves the text by collapsing duplicated objects, compressing content streams, and leaving the pages unchanged. This method often results in a much smaller file where the text remains readable, as demonstrated by a specific document where lossless repacking reduced it to 3.4 times smaller than the best raster result, maintaining complete text extractability.
The reason rasterizing text in a PDF turns it into a picture lies in the document's structure. A PDF page is essentially a list of drawing operations, and text is represented by fonts and glyph positions, which can be selected, searched, copied, indexed, or parsed by various tools. When rasterized, the text is replaced with a bitmap, eliminating glyph positions and rendering it unusable for tasks requiring text manipulation.
This process is largely silent, and its effects may only surface weeks later when the document fails to compress properly, leading to requests for a fresh copy. The issue arises when a text document has already been compressed, repacked, and saved multiple times, leaving its text streams uncompressed. A simple fix involves iterating through every indirect object in the document, identifying raw streams without a /Filter, deflating them, and encoding them with FlateDecode, ensuring that the compressed size is smaller than the original.
This process can be implemented in about twenty lines of code, making it practical to ship and implement.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.