Repository navigation
fix(write): keep WebP images as WebP in client exports - #37
Merged
Merged
Conversation
The client export resolver re-encoded every non-PNG/JPEG image as PNG with Flutter's Image.toByteData. Now that stored images are WebP, every image took that path, and on Flutter web (skwasm) the PNG can come back on a larger transparent canvas when other images are rasterized at the same time. Images are now described from their header like on the server (describeExportImage): Markdown and HTML exports keep the WebP (images/<n>-<slug>.webp), and the DOCX/ODT/RTF/EPUB exporters convert opaque lossy WebP to JPEG (q 90) and other WebP to PNG in pure Dart. Sheets' Download image names the file by the sniffed type instead of assuming PNG for server bytes. The blog guide's and specs/18's webhook examples show WebP assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Summary
Follow-up to #36. Images exported from Write as Markdown with images came out as
.pngfiles, and some had a large transparent area around the picture.Image.toByteData. Since feat(files): store uploaded images as WebP with Pixtronaut; drop BMP #36 every stored image is WebP, so every image took that path. On Flutter web (wasm),toByteData(format: png)resizes a shared offscreen canvas and then copies the whole canvas into the PNG, and those steps aren't atomic. When another image is rasterized in between, the PNG gets that canvas's size, with the image in its top-left corner. A reported file was 1627 × 2000 with the picture at 1:1 in the corner.decodeForExportdescribes PNG/JPEG/GIF/WebP from their header withdescribeExportImage, as the server-side exports already did, and passes them through unchanged. Markdown (images/<n>-<slug>.webp) and HTML exports keep the WebP. Only other formats (SVG, AVIF ofhttpsimages) still go through Flutter.prepareOfficeImage). Opaque lossy WebP (photos) now becomes JPEG at quality 90 instead of a much larger PNG; lossless or transparent WebP becomes PNG. PDF decodes WebP itself, unchanged.assets[].type/nameand the asset download'sContent-Typecome from the stored file (image/webp,*.webp), andsubmission_cover_testchecks this. The webhook examples indocs/blog-integration.mdand specs/18 now show a WebP asset.This fix was first pushed to
mainby mistake (595119b) and reverted there (3a62134). This PR brings it back.Testing
dart analyzeanddart formatclean.export_service_test(a WebP passes the client resolver unchanged and is named.webp) andoffice_images_test(lossy opaque WebP → JPEG; lossless or transparent WebP → PNG).wonky_write_coretest/export(295), Writetest/features/exportandtest/features/images, and the Sheets object/image command tests pass.🤖 Generated with Claude Code