Vector-preserving dark-mode (colour inversion) for PDFs
Project description
pdf-invert
Convert a PDF into a dark-mode version by inverting its colours — without rasterizing. Text stays selectable and searchable, vector graphics stay vector, and the file stays roughly the same size.
$ uvx pdf-invert paper.pdf
Wrote paper-dark.pdf
Usage
pdf-invert INPUT [-o OUTPUT] [--invert-images] [--linearize] [-q]
INPUT— the source PDF.-o, --output— destination (default:<name>-dark.pdfbeside the input).--invert-images— also invert raster images. Off by default so photos, figures, and logos don't become negatives.--linearize— linearize output for faster web viewing.-q, --quiet— suppress warnings.
How it works
For every colour-setting operator in every content stream (page bodies, form
XObjects, tiling patterns, Type3 glyphs, annotation appearances), each channel
value v is replaced with 1 - v, and a black backdrop is placed behind the
page. Because only colours change, the text and vector geometry are untouched.
A few deliberate choices make this robust on real documents — establishing white
as the default colour (so text drawn without an explicit colour doesn't vanish
on the black backdrop), tracking the current colourspace so sc/scn are only
inverted when that's meaningful, visiting shared objects once, and never
entering soft masks. See KNOWN_LIMITATIONS.md for what's
out of scope.
Why not Ghostscript / rasterizing?
Ghostscript's setcolortransfer inverts at the render pipeline and is excellent,
but it needs a system binary and inverts everything, including images. A
rasterize-and-invert approach loses selectable text and bloats file size (often
20×). pdf-invert is pure Python (pikepdf), installs anywhere uv/pip
reaches, keeps text, and lets you preserve images.
Development
uv run pdf-invert some.pdf # run from source
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pdf_invert-0.1.0.tar.gz.
File metadata
- Download URL: pdf_invert-0.1.0.tar.gz
- Upload date:
- Size: 9.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30383c4add8518118c6df6bb2721b1010a9192acbac5216080b962c0f64fd02d
|
|
| MD5 |
2d28c757c03fd67c5f1fe968f0dc673c
|
|
| BLAKE2b-256 |
259d47698379e4b1ab86dd270f66bba4a140926e65c640d697479a4557f3e2bd
|
File details
Details for the file pdf_invert-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pdf_invert-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f0cc0073d76ef8aa308092491112e57c88fe67d17c4b9562d71e7d726588f63
|
|
| MD5 |
be7915e922b55a98545674ab7ab3b743
|
|
| BLAKE2b-256 |
50da3a1a2af2de61e0156e48bfe3cd476c7869318459ae910237fc5688eba83b
|