Replacing Acrobat Pro: the wrong turns compressing PDFs

DHSeaDev — Chrome Extensions, Windows Tools, & Idle Games

A desktop PDF optimizer can replace the compress-and-clean routine many offices run in Acrobat Pro: strip the hidden information, shrink the scans, strip it again. I spent several rounds building one inside PDF Tools, the internal utility a legal-support office uses for merging, splitting, renaming and moving files. The goal was a copy that fits a 6.9 MB upload limit. The early versions were wrong in ways that every size check approved.

What was the Acrobat routine, and what does the tool do instead?

The routine was three steps. Remove hidden information first, and if the file is now small enough, stop. If not, optimize at the lowest quality setting, then remove hidden information again, because optimizing can leave new residue behind.

The tool copies that order. Pass one rewrites the file clean: metadata, embedded files, scripts, thumbnails, orphaned objects and every earlier saved revision are gone, and a full rewrite is what actually destroys the revision history. If that already fits, nothing else happens and the text stays searchable. Pass two goes straight to the most aggressive image setting instead of walking down from a gentle one. Pass three cleans the result again. The original is never touched; everything is written to a copy.

Why did the first version leave a 30 MB file almost unchanged?

Version one tried ten settings from gentle to harsh and kept the first that fit, which was slow and aimed at the wrong target: the goal was the smallest copy, not the prettiest one that squeaked under the limit. Worse, it could not see many scans at all. Scanner output often wraps a page in a form container, and the image walker only looked one level down, so it reported zero images, called the file vector-only, skipped every compression step and wrote it back unchanged.

I reproduced it on a 21.58 MB colour scan I built with its images inside a form container. Before the fix: zero images found, 21.58 MB in and 21.58 MB out. After walking into the containers: twelve images found and 3.66 MB out.

Why did a label say 120 DPI greyscale when nothing had shrunk?

The next wrong turn came from a real file. A 30.48 MB filing came back at 16.69 MB, labelled 120 DPI greyscale. That size was suspiciously consistent with colour-to-grey conversion alone and no resampling.

The resize only fired when the measured resolution was higher than the target. When the measured number came out wrong or low, the condition was simply false, the image stayed at full size, and the report still named the setting it had not applied. The fix computes the target pixel size from page geometry, width in inches times target DPI, because page boxes are reliable and derived resolution is not. The widest image went from 2550 pixels to 1020, exactly 8.5 inches at 120 DPI, and a test now asserts the pixel dimensions shrink rather than that the file got smaller. A smaller file is not evidence that the operation you named ran.

What was actually taking up half the file?

Not the images. The arithmetic gave it away: 30.48 MB minus 15.59 MB of image data leaves 14.89 MB that no image setting touches, more than double the limit by itself. So I wrote a byte census that classifies every stream in the file.

Part of the 50-page filingSizeShare
Scanned images15.59 MB51%
Page text and drawing commands (the invisible OCR layer)13.89 MB46%
Embedded fonts0.61 MB2%
One real filing, 193 images, 139 of them inside form containers.

The searchable text layer was nearly half the file. Squeezing the scans harder could never reach the limit, so the only operation that guarantees a size is flattening: re-render every page as an image and rebuild the document, so the output depends on page count, resolution and encoder rather than on what the original contained. That filing went from 30.48 MB to 5.36 MB, 82% smaller, at the cost of its text layer.

Why does the finished tool have one setting?

Once the escalation was right, every checkbox was a way to be confused. The final tool has a single control, the maximum file size, and escalates on its own: clean only, then shrink the scans (colour before resolution), then flatten as a last resort. A column in the results says which step each file needed, so the operator always knows whether the output is still searchable. A guard test pins the control list so quality knobs cannot creep back in.

Measured on test scans I generated, smallest-first took one file from 34.01 MB to 1.97 MB in 7.2 seconds, where the ladder had managed 5.07 MB in 15.4 seconds, and a 21.58 MB scan to 1.37 MB in 4.0 seconds. A file that fits after cleaning alone runs a single pass and touches no image.

What does it still not do?

Flattening destroys the searchable text layer, annotations, form fields and bookmarks, so it asks for confirmation and says so in the results. There is no OCR. Digital signatures are the subtle case: only an applied cryptographic signature is voided by a rewrite, while an empty signature field or an ink signature on a scan is not, and my first detector warned on blank court forms until I made it require an applied signature. The tool now optimizes signed files and warns, since the original is never altered and refusing left no route through it. If a filing cannot fit even after flattening to black and white, the honest answer is splitting the document, and the tool says that instead of shipping an over-limit file.

One licensing note: the engines that could do more were all AGPL, so I rejected them and used permissively licensed libraries, because bundling one into an executable that staff copy around is an unresolved combined-work question.

What is the takeaway?

Every wrong turn was a measurement of the wrong thing: a size that fell for the wrong reason, a label that named work that never happened, a diagnosis that counted the part I could see. Once the census existed, the guessing stopped. The same habit runs through measuring the wrong thing, and the small tools around this one are in the fifteen-second problem.

Leave a Reply

Your email address will not be published. Required fields are marked *