Skip to content

Refuse images over the browser canvas size limits on import - #146

Open
officialasishkumar wants to merge 1 commit into
vycdev:developfrom
officialasishkumar:fix/issue-125-oversized-image-import
Open

officialasishkumar wants to merge 1 commit into
vycdev:developfrom
officialasishkumar:fix/issue-125-oversized-image-import

Conversation

@officialasishkumar

Copy link
Copy Markdown

Importing an image larger than a browser canvas can hold, such as the 17000×17000 PNG from #125, looked like it worked: the size badge showed the new dimensions, but the 2D preview stayed blank and the app stayed sluggish with no message. CanvasPreview copies the image into canvases at full size. Browsers refuse oversized canvases without throwing, so the canvases just stay blank:

  • Chromium (and WebView2 in the Windows desktop app) and WebKit refuse more than 268,435,456 pixels (16384×16384).
  • Firefox refuses any side over 32,767 pixels.

Change

The main image import now refuses an image outside either limit, before it reaches image history. It goes through the same path as unreadable files from #107: the object URL is revoked, history and swatches are left alone, and the dismissible import notice explains why:

“huge.png” is 17000×17000 pixels, which is too large to open. Your current image was kept. Resize it to 16384×16384 pixels or smaller and try again.

  • src/lib/imageFile.ts adds fitsImageCanvasLimits and the limit constants, with each engine's limit documented.
  • useImageImport reads the decoded size before closing the image (a closed ImageBitmap reports 0×0) and reports a new tooLarge error kind. Like the existing kinds, it stores the name, size, and whether an image was kept, not a translated string, so the notice follows language changes.
  • The check is in useImageImport rather than validateImageFile. The Stack Matrix photo picker also uses validateImageFile, but it draws photos at 1200 px at most, so very large photos keep working there.
  • App.tsx builds the notice text in a small helper instead of a three-level ternary. Each translation key stays a literal so check:i18n still checks it.
  • Two new strings in all 12 locales. The Loading Images guide describes the limits in all 12 languages. Unreleased changelog entry under Fixed.

This PR refuses the image rather than offering to downscale it. The issue lists either as acceptable, and downscaling only to the canvas limit would still leave a very slow image (the issue measured about 19 s to recover at 12000×12000). If you'd prefer a downscale option in the notice, I can add it as a follow-up.

Fixes #125

Tests

  • tests/imageFile.test.ts: fitsImageCanvasLimits at and just past both limits.
  • tests/e2e/image-import-error.spec.ts (@smoke): the test generates a real 32768×8 PNG and imports it over a loaded image. It checks the notice text, that the current image is kept, that no history entry is added, and the "no image" wording after Remove image. It also checks that a 32767×8 PNG still imports. The test fails on develop, where no notice appears, and passes with this change.
  • With a temporary spec that imported the issue's 17000×17000 PNG in Chromium, the notice appeared, the starter image stayed, and a page.evaluate round trip took 15 ms right afterwards.
  • npm run lint, npx tsc -b, npm run check:i18n, Prettier on the changed source and test files, and the image-import-error and image-reimport e2e specs (10 passed) all pass.

The privacy and terms e2e jobs currently fail on develop because of #143, which is fixed separately.

@chatgpt-codex-connector

Copy link
Copy Markdown
Codex Review Summary: ❌ Failed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ❌ Failed 2026-11-11T16:08:48.075091Z
We couldn’t complete this review. Comment @codex review to try again.
0d7fe5e PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Importing an image larger than a browser canvas can hold, for example a
17000x17000 PNG, appeared to work: the size badge showed the new
dimensions, but the 2D preview stayed blank and the app stayed
unresponsive for minutes. CanvasPreview copies the image into canvases
at full size, and browsers silently refuse canvases over 268,435,456
pixels (16384x16384) in Chromium, the WebView2 desktop app and WebKit,
or with a side over 32,767 pixels in Firefox. The refused canvases stay
blank instead of throwing, so the rest of the pipeline kept working
against unusable canvases (vycdev#125).

useImageImport now reads the decoded size before closing the image and
refuses anything outside both limits, through the same path as
unreadable files: the object URL is revoked, nothing is pushed to image
history, the swatches are left alone, and the dismissible import notice
explains the problem. The check lives in the main import rather than
validateImageFile because the Stack Matrix photo picker also uses that
helper and draws photos at no more than 1200 px, so very large photos
still work there.

- src/lib/imageFile.ts: add MAX_IMAGE_SIDE, MAX_SQUARE_IMAGE_SIDE,
  MAX_IMAGE_PIXELS and fitsImageCanvasLimits, with the per-engine
  limits documented.
- useImageImport: new 'tooLarge' error kind carrying the file name, the
  image size and whether the current image was kept, so the notice
  follows language changes like the existing kinds.
- App: build the notice text in a small helper instead of a nested
  ternary. Every translation key stays a literal for check:i18n.
- Two new strings in all 12 locales name the image size and the
  16384x16384 limit, with and without the "current image was kept"
  sentence.
- Loading Images docs, in all 12 languages, describe the limits.
- Unreleased changelog entry under Fixed.

Tests: unit coverage of the limits at and just past both boundaries,
and a @smoke e2e test that imports a real 32768x8 PNG, generated in the
test, and checks the notice text, the kept image, that history and the
"no image" wording are unchanged, and that a 32767x8 PNG still imports.

Fixes vycdev#125
@officialasishkumar
officialasishkumar force-pushed the fix/issue-125-oversized-image-import branch from 0d7fe5e to 69ebcfd Compare November 11, 2026 16:32
@officialasishkumar

Copy link
Copy Markdown
Author

The e2e jobs here failed in the "Install Playwright system dependencies" step, before any test ran: the runner couldn't resolve azure.archive.ubuntu.com (Temporary failure resolving), twice in a row. "Lint, build, and unit tests" passed. I can't rerun jobs on this repository, so could you rerun the failed jobs once the runners recover?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant