Contact Sheet Generator
Drop in a batch of photos, print a paginated, numbered contact sheet — nothing is ever uploaded anywhere.
Drop in a batch of JPEG, PNG, WebP, or GIF photos, pick a grid (columns × rows), a page size (US Letter or A4), and a label style, then generate a clean, correctly-paginated printable contact sheet. Every photo is numbered so a client can circle their favorites on paper. Runs entirely in your browser — nothing is uploaded, there's no per-batch photo cap, and it works without an active Creative Cloud subscription. One-time purchase, works offline forever.
What it does
What it does: Redraws each dropped photo onto a canvas and re-encodes it at a print-appropriate resolution, then lays every thumbnail into a CSS grid sized to fit exactly N columns × M rows per page, with a filename and/or sequence number underneath. Photos are chunked into pages up front — a 200-photo batch at a 4×5 grid becomes 10 clean pages, not one broken mega-page or an accidentally-cut-off last row. Pagination is driven by the browser's own @page CSS and break-after rules (dynamically sized to the exact chosen page dimensions), so "Print / Save as PDF" produces the same layout you already see in the on-screen preview — no separate PDF library, no separate preview-vs-print representation to keep in sync by hand.
Who it's for: A photographer (or anyone managing a big batch of shoot photos) who needs a client to review and mark favorites on paper instead of scrolling a gallery link, without owning a Creative Cloud subscription just to get Lightroom's or Photoshop's built-in contact-sheet feature.
Example scenario: A wedding photographer delivers 200 photos from a Sunday shoot. Instead of asking the couple to scroll a phone gallery and try to remember which ones they liked, the photographer drops all 200 into this tool, picks a 4×5 grid on US Letter, generates the sheet, and prints 10 clean numbered pages. The couple sits down with a pen and circles their favorites by number — "12, 47, 103, 156" — and that list goes straight into the edit selection instead of a vague verbal description.
What it explicitly does not do:
- Does not upload, store, or remember your photos between sessions — reload the page and the last batch is gone.
- Does not do any photo editing (crop, color, retouch) — it only resizes and lays out what you gave it.
- Does not produce full-resolution prints of individual photos — thumbnails are capped at 700px on the long edge for print embedding, which is correct for a proof/reference sheet (dozens of small photos per page) but not a substitute for printing one photo at full size.
- Does not guarantee every corrupted file will be caught and flagged. Browsers differ in how leniently they decode a truncated/corrupted JPEG — Chromium-based browsers (Chrome, Edge, Brave) will often render a partial, visually garbled image from a truncated file rather than erroring, while Firefox and Safari's WebKit engine correctly reject the same file as undecodable. Both are legitimate native browser behaviors, not a bug in this tool — genuinely broken files (0-byte, non-image, or badly-enough-corrupted that no engine can decode them) are always caught and skipped with a clear per-file error, in every browser tested.
- Does not batch-rename, reorganize, or otherwise modify your original files on disk — they're read, never written.
Features
- Lays out any batch of photos into a configurable grid (columns × rows, with quick presets: 3×4, 4×5, 5×6, 6×8) and paginates automatically — a 200-photo batch at 4×5 becomes exactly 10 clean pages
- Every photo is numbered in a stable, verified sequence, so a client can circle favorites on a printed page by number (labels can show the number, the filename, or both)
- Supports both US Letter and A4 page sizes, with page geometry computed from the actual chosen page size — not a fixed layout that happens to roughly fit
- A bad file (corrupted, empty, wrong type) is skipped with a clear per-file error message — it never breaks the rest of the batch or the page layout
- Live on-screen preview shows the exact same paginated layout that prints — no separate "what you'll get" guesswork
- Runs entirely offline in your browser — no network requests, no analytics, no per-batch photo cap, no Creative Cloud subscription required
Browser support
| Platform | Result | Notes |
|---|---|---|
| Desktop Safari (macOS) | Full | Opened and visually confirmed in the real, installed Safari app (empty-state screenshot). Full functional flow — batch decode, error handling for bad files, grid/pagination generation — additionally verified through WebKit, the same engine Safari runs on, via CDP automation (drag-and-drop itself can't be scripted without OS Accessibility permission, which this machine can't grant; see the "how this was tested" note below). |
| Desktop Chrome (macOS) | Full | Opened and visually confirmed in the real, installed Chrome app (empty-state screenshot). Full functional flow verified through Chrome's own Blink/Chromium engine, including print-to-PDF output checked byte-by-byte with `pypdf`/`pymupdf` at both US Letter and A4, and a 200-photo performance batch. |
| Desktop Firefox (macOS) | Full | Opened and visually confirmed in the real, installed Firefox app (empty-state screenshot). Full functional flow verified through Firefox's own Gecko engine — including the one genuine cross-engine difference found during testing: Firefox correctly rejects a deliberately truncated test JPEG as a decode error, where Chromium renders a partial garbled image instead (see the long description above). |
| Edge / Brave | Not separately tested | Both are Chromium-based like Chrome, where the tool was confirmed Full; neither is independently installed on this machine. |
| iOS Safari (iPhone/iPad) | Not verified | No physical iOS device available. Drag-and-drop of files onto a web page isn't available on iOS regardless of this tool; the click-to-browse fallback (``) is a standard API that should work — this is a reasonable inference, not a verified test, and is not claimed as such. |
| Android Chrome | Full | Tested on a real Android device in Chrome — works. |
| Small-viewport / touch | Not verified | Not checked in this pass, even via desktop devtools emulation. |
How this was tested: this machine cannot grant the Accessibility/System-Events permission that OS-level UI-scripting (real drag-and-drop, clicking through a native file picker) requires. Real installed Safari/Chrome/Firefox were used for what they're good for here — genuine visual/rendering confirmation via screenshot. Actual interaction (dropping files, clicking Generate, printing) was driven programmatically via Playwright's own bundled Chromium, Firefox, and WebKit binaries over CDP — the same three rendering engines Chrome/Edge/Brave, Firefox, and Safari respectively use — which is real functional coverage of all three engines, not a Chromium-only check. A 55-photo batch (50 real photos + 5 deliberately-broken files: 0-byte, corrupted, fake-extension, non-image, and one 4000×3000/360KB "large photo" file) was run through full decode → generate → print on all three engines, plus a 200-photo/7.7MB batch for pagination and performance. The one real defect this testing found — a leftover, un-hidden preview heading that printed as a spurious blank leading PDF page — was fixed and re-verified (see Phase 2/4 notes below).
FAQ
Does my file get uploaded anywhere?
No. The entire tool is one static HTML file with no server component and no network calls. You can open it with your Wi-Fi off, or read the page's source yourself to confirm there's nothing that sends data anywhere.
Does this work on my iPhone/iPad?
Not tested on a physical device, so it isn't claimed as verified either way. The click-to-browse file picker is a standard API that should work on iOS Safari, but drag-and-drop of files onto a web page isn't available on iOS regardless of the tool.
What happens to my file if I lose the download?
Nothing is stored by the tool anywhere — your original photos are untouched on your computer the whole time, so you can just generate the sheet again. If you reload the page before printing/saving, you'll need to re-drop the batch; nothing is held in memory across a reload.
Can I use this for client or commercial work?
Yes — personal and commercial use are both fine, including client deliverables and proofing.
Is there a subscription?
No. One-time purchase, yours to keep and reuse forever — that's the whole point: Lightroom Classic and Photoshop's own contact-sheet features are genuinely good, but both live behind an active Creative Cloud subscription (from $9.99/month). This tool does the one specific job without it.
Does this need Photoshop or Lightroom?
No. It doesn't touch, require, or integrate with any Adobe product — it's a completely independent single HTML file.
How many photos can it handle?
No hard cap is enforced. It was tested cleanly on a 200-photo/7.7MB batch (decode ~0.4s, sheet generation ~0.9s, PDF export ~0.03s in Chrome) producing 10 correctly-paginated pages, plus a separate 4000×3000/360KB single large photo (decoded in 24ms). Real camera-original JPEGs from a DSLR or mirrorless camera are typically several MB each at 20+ megapixels; this wasn't tested at that exact scale, but since per-photo decode cost tracks pixel count more than file size, and a single 12-megapixel photo decoded in 24ms during testing, a real 200-photo batch of full-size camera JPEGs should reasonably complete in the low single-digit seconds — that's a reasoned expectation from the numbers actually measured, not a literal test at that scale, and it's stated that plainly rather than dressed up as one.
- ✓ Runs 100% offline in your browser
- ✓ Single HTML file — no install, no dependencies
- ✓ No account, no telemetry, no tracking
- ✓ Buy once — yours forever
After checkout you get an instant download link. Open the file in any modern browser and it just works.
Pairs well with
✓ runs entirely on your device — Wi-Fi off? Still works.
accounts sign-ups cloud uploads none
✓ your files stay where you put them
Prefer to try before buying? The browser versions of every tool run free at tools.untracked.tools — no upload, ever.