Client: International Salon Supplies (internal tooling)
Role: Developer
Period: Sep 2025
Status: Internal tools (v1)
Tech stack: Chrome Extension (Manifest V3), html2canvas, jsPDF, Python, Tkinter, pypdf, PyInstaller
Staff regularly produced PDFs too large to email. I built two complementary tools on the same day: a Chrome extension that turns web pages into compact, image-based PDFs, and a portable Windows app that compresses existing PDFs with no installation. This post covers the approach, the packaging, and what v2 needs.
The problem
Chrome's built-in "Save as PDF" can produce very large files from image-heavy web pages, and scanned documents aren't much better. Staff kept hitting email attachment limits.
Tool 1: Webpage → compact PDF (Chrome extension)
Trade vector fidelity for file size. Instead of printing the page, the extension rasterises it and controls the image quality.
- The popup lets users choose quality (high, medium, low), page size (A4, Letter, Legal), orientation, whether to keep backgrounds and whether to remove ads. Choices sync with
chrome.storage.sync. - The content script temporarily hides interactive and media elements, renders the page with html2canvas (capped scale and dimensions), encodes it as JPEG at the chosen quality, and builds the PDF with jsPDF using compression and fast image mode. It then restores the page exactly as it was.
- Filenames are generated from the cleaned page title plus the date. Browser-internal pages that extensions can't access get a clear error message instead of a cryptic one.
Tool 2: Portable PDF Compressor (Windows)
Ship Python to people who've never heard of Python.
- A Tkinter GUI: add PDFs, choose an output folder (it defaults to a folder on the Desktop), pick a compression level. Originals are never touched, and outputs get a
_compressedsuffix. - Compression runs on a background thread. All UI updates are marshalled back through
root.after(...)to keep Tkinter thread-safe, and the final message distinguishes full success, partial success and failure. - A build script runs PyInstaller to produce a single windowless executable (~12 MB), then assembles a portable folder with the exe, a README and a launcher. A batch file checks Python, installs requirements and builds.
Honest limitations (and v2)
These were quick v1 tools, and each has clear limits:
- The extension captures the rendered viewport, so very long pages need proper full-page capture and correct pagination.
- The compressor only compresses content streams. Real savings on image-heavy or scanned PDFs need image downsampling, for example with Ghostscript.
- v2 should report measured before/after sizes rather than relying on expectations.
Takeaway
Small tools earn trust by being easy to use: one click in the browser, one double-click on the desktop. The packaging work is as important as the core logic.