~/sabarish.dev
← all posts

~/posts/dark-pdf-dark-mode-converter

dark: a Streamlit PDF dark-mode converter

Sabarish R2 min read
  • python
  • streamlit
  • pdf
  • tooling

Every tool in the box doesn't need to be a platform. dark is the opposite of my usual writeups: a single-purpose Streamlit app that takes a PDF, inverts its colors, and hands back a dark-mode copy for night reading.

Repo: github.com/SabarishR08/dark

How it works

The whole pipeline is one function and two dependencies (streamlit, pymupdf):

  1. Open the PDF in memory — PyMuPDF (fitz) loads the uploaded bytes, no temp files
  2. Render each page at 2× resolution — the Matrix(2, 2) render keeps text and lines crisp after inversion, since a dark-mode page is a screenshot-like bitmap, not live text
  3. Invert every pixel — pix.invert_irect(pix.irect) flips the whole raster in one call
  4. Rebuild the PDF page by page — each inverted pixmap is inserted onto a fresh page at the original dimensions
  5. Compress before saving — garbage=4, deflate=True keeps the output reasonable even when the input was bloated

A progress bar tracks the page loop, and the result is returned as a bytes buffer for the download button — dark_<original-name>.pdf.

Why rasterizing?

A "dark PDF" is usually made by rewriting the text layer, which is fragile: fonts, annotations, and scanned pages all break. Rendering to pixels and inverting is the brute-force approach that works on any PDF — the only trade-off is that the output is a scanned-style copy rather than editable text, which is exactly what night reading needs.

What I'd do next

  • Auto white-page detection — skip pages that are already dark
  • Threshold instead of blind inversion — pure inversion turns dark backgrounds light; a luminance-aware remap preserves contrast better
  • Deploy it — it's currently a local tool; a Streamlit Community Cloud link would make it shareable

A focused tool that does one thing well — the PDF equivalent of a dark-mode extension for files instead of websites.