Downscale previews and cap export decode to fix mobile blackouts#74
Merged
Conversation
On-screen frames rendered the original multi-megapixel files, so a sheet full of phone photos held hundreds of MB of decoded bitmaps — past the mobile browser image-memory budget, which silently dropped some to blank/black. The PDF export decoded each file at full resolution too, so a photo that went dark on screen also went missing from the export. Add a client-side preview pipeline: each photo is decoded once (serially, respecting EXIF orientation) to capture its natural size, default its window orientation, and build a small (<=1280px) JPEG preview object URL. Every on-screen <img> now uses that preview; the full-resolution file is kept only for export. Previews are generated for uploads, restored sessions, and opened projects, and revoked alongside the original URL. For export, decode via createImageBitmap capped to ~3600px (well above 300 DPI for any A4 card) and close() each bitmap immediately, so a large sheet can't exhaust memory mid-render. There is no server involved — the resize happens entirely in the browser, so nothing leaves the device.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes intermittent blank/black photos on mobile (both on-screen and, correspondingly, missing from the exported PDF).
Root cause. Every on-screen frame rendered the original multi-megapixel file, so a sheet of phone photos held hundreds of MB of decoded bitmaps — past the mobile browser's image-memory budget, which silently drops some to blank/black. The PDF export decoded each file at full resolution too, so a photo that went dark on screen also went missing from the export.
Preview pipeline. New
lib/image.ts+ a serialized decode queue in the photo store. Each photo is decoded once (respecting EXIF orientation) to capture its natural size, default its window orientation, and build a ≤1280px JPEG preview object URL. Every on-screen<img>(sheet cards, filmstrip, sidebar, strips) usespreviewUrl ?? url. Previews are built for uploads, restored sessions, and opened projects, and revoked alongside the original URL. Decoding is serialized so we never hold several full-res bitmaps at once.Export pipeline.
rasterizeJpegdecodes viacreateImageBitmapcapped at ~3600px (well above 300 DPI for any A4 card) andclose()s each bitmap immediately, so a large sheet can't exhaust memory mid-render. Falls back gracefully where the resize/orientation options aren't supported.Print quality unchanged; EXIF orientation preserved; entirely client-side (nothing leaves the device). Typecheck, lint, build green.