Remove blank and duplicate pages
A PDF that passes through several people picks up junk: blank separator pages from double-sided scanning, whole sections re-inserted by the third forwarder. tidy drops both in one command and tells you exactly what went and why.
Local only, and deliberately not AI. This runs entirely on your own machine, free, as part of the open source pdfblah CLI. Nothing is uploaded, and no model guesses at your content: the decisions are pixel arithmetic and a hash, the same result every time. That is the right tool for sensitive documents.
What counts as blank, what counts as duplicate
The rules are deterministic and conservative, tuned to never eat a page you meant to keep:
- Blank means the page renders with almost no ink (under 0.3% of its pixels, ignoring the scanner shadow at the edges) and has no extractable text. A page holding only a "Page 4" footer, or "this page intentionally left blank", survives.
- Duplicate means the page's rendered pixels exactly match an earlier page. Digitally copied repeats match; a re-scan of the same sheet (same words, new pixels) does not. Exactness over guessing.
- Nothing is silent. The report names every dropped page and the reason,
--dry-runshows it all before anything is written, and a file whose every page would go is refused rather than written empty.
How to do it
pip install "pdfblah[app]"
# preview: which pages would go, and why (writes nothing)
pdfblah tidy in.pdf --dry-run
# drop blank pages and exact repeats
pdfblah tidy in.pdf -o tidy.pdf
# only dedupe, keep the blanks (or the reverse: --keep-duplicates)
pdfblah tidy in.pdf -o tidy.pdf --keep-blank
# a whole folder
for f in *.pdf; do pdfblah tidy "$f" -o "tidied/${f%.pdf}-tidy.pdf"; done
The report looks like this:
tidy: kept 34 of 41 page(s), dropped 7 -> tidy.pdf
page 2: blank
page 9: duplicate of page 3
...
Tips
- Always
--dry-runfirst on a document that matters. It costs seconds and shows the exact drop list. - Gray or noisy scans can make a truly blank page read as inked. Raise the threshold with
--blank-ink 0.01, or run Clean scan first so blank paper is actually white. - Repeats that were re-scanned rather than copied will not match on purpose. Use split and page ranges to cut those by hand.
- Tidy first, then combine into a binder: the table of contents and page numbers come out right when the junk is already gone.