Downscale captures too large for the browser to render#54
Merged
Conversation
Browsers refuse to decode an image past ~32,767px on a side (Skia's kMaxDimension) and show it as a broken/corrupt image in the report. Full-page mobile captures cross this routinely: a narrow viewport stacks content into a very tall page, and a 2x deviceScaleFactor doubles the pixel height again. The PNG on disk is valid — only the browser viewing the report can't paint it. - New src/downscale.mjs: an area-filter (box-average) resampler plus helpers to compute display dimensions and shrink an oversized PNG. - compare writes a downscaled display copy to a new .reglance/display/ directory for any image over the limit and points the report at it. pixelmatch still runs against the full-resolution originals, and the promoted baseline is never modified. - The comparison view shows a "Downscaled" banner with the original and shown dimensions whenever an image on screen was shrunk. - capture warns at screenshot time when it writes a PNG past the limit (read straight from the IHDR header, no full decode), so the cause is visible before the report is built. Adds tests for the resampler, the display-dimension math, the PNG header reader, and the report's display/scaled wiring. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
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.
Problem
Browsers refuse to decode an image taller or wider than 32,767px (Skia's
kMaxDimension) and render it as a broken/corrupt image — the console reports the image as corrupt. Full-page mobile captures cross this routinely: a narrow viewport stacks content into a very tall page, and adeviceScaleFactorof 2 doubles the pixel height again. The capture PNG on disk is valid; only the browser viewing the report can't paint it, so some screenshots silently fail to load in the report.What this does
src/downscale.mjs(new) — an area-filter (box-average) resampler, plusdisplayDimensions(clamp the longest side to the limit, keep aspect ratio) anddownscaleToDisplay. Area averaging keeps shrunk text and 1px borders legible.comparewrites a downscaled copy of any oversized image to a new.reglance/display/directory and points the report at it. pixelmatch still runs at full resolution against the originals, and the promoted baseline incontrols/is never modified — only the displayed copy is shrunk.capturewarns at screenshot time when it writes a PNG past the limit — read straight from the IHDR header (a 24-byte read, no full decode) — so the cause is visible before the report is built.Why downscale on display rather than at capture
Keeping the full-resolution capture as the source of truth means pixel diffs stay accurate and the baseline isn't perturbed by a height change crossing the limit. Only the report's rendered copy is shrunk.
Test plan
npm run lint— cleannpm test— 124 pass. New coverage for the resampler (flat-color and boundary averaging),displayDimensionsclamping/aspect-ratio/guards, the PNG header reader, and the report linking display copies + surfacingscaled.home-mobilecapture was 34,162px tall: it now gets a 748×32767 display copy, the report links it, the banner renders, and pages under the limit are untouched.🤖 Generated with Claude Code