Repository navigation
Add ResizeImagePolicy.cover - #194665
Add ResizeImagePolicy.cover#194665
Conversation
Add a cover policy to ResizeImage. It decodes the image at the smallest size that covers the width x height box and keeps the aspect ratio of the image, like BoxFit.cover. The aspect ratio comes from the intrinsic size that the decoder gives, so the caller does not need to know the image size. Before this change, a caller that paints with BoxFit.cover and does not know the aspect ratio had two options: decode at full size, or use ResizeImagePolicy.fit or one cacheWidth/cacheHeight value, which can decode an image that is too small for the box. The policy requires both width and height. It uses integer math with round-up, so the decoded image always covers the box and a box that matches the aspect ratio does not get one extra pixel. It does not scale up unless allowUpscaling is true. Fixes flutter#61987
There was a problem hiding this comment.
Code Review
This pull request adds a new ResizeImagePolicy.cover policy to ResizeImage, which scales an image to cover a specified bounding box while maintaining its aspect ratio. The changes include adding the enum value, enforcing that both width and height are non-null via assertions when using this policy, implementing the cover scaling logic, and adding corresponding unit tests. I have no feedback to provide.
victorsanni
left a comment
There was a problem hiding this comment.
LGTM with some comments.
Adding new enum value is a breaking change, cc @chunhtai who has an RFC for exactly this.
|
Thanks, added both tests. On the enum value: Google testing passes, so this is not a breaking change under the current Tree hygiene rules. It can still break code that has an exhaustive |
|
Hi, is this ready for re-review? Please remember to request a review if it is, so it gets back into the review queue. |
- Assert that the cover box is not empty, and test a width or height of 0. - Keep the intrinsic size when either derived side reaches it, so that mirrored inputs give mirrored outputs. - Document that cover needs both width and height. - Run the null width or height assertion test on web too. - Test that a different policy makes ResizeImage unequal.
victorsanni
left a comment
There was a problem hiding this comment.
LGTM, thanks for the fix!
|
autosubmit label was removed for flutter/flutter/194665, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label. |
flutter/flutter@09175cd...e36b370 2026-11-07 [email protected] Roll Fuchsia Linux SDK from KIc0XZbhLmvDpTluZ... to Sf2yvdTiFXAKkfLkD... (flutter/flutter#196160) 2026-11-07 [email protected] Roll pub packages (flutter/flutter#196155) 2026-11-07 [email protected] [iOS a11y] Use a real `UIScrollView` as a11y scrollable container (flutter/flutter#195731) 2026-11-07 [email protected] Add ParagraphStyle.hyphenCharacter to dart:ui (flutter/flutter#195345) 2026-11-07 [email protected] Roll pub packages (flutter/flutter#196143) 2026-11-06 [email protected] [Linux] Fix layer position when compositing without glBlitFramebuffer (flutter/flutter#196083) 2026-11-06 [email protected] Add support for riscv64 desktop linux engine (flutter/flutter#178712) 2026-11-06 [email protected] Add ResizeImagePolicy.cover (flutter/flutter#194665) 2026-11-06 [email protected] Roll Skia from f533d4034900 to b11315d0a096 (6 revisions) (flutter/flutter#196138) 2026-11-06 [email protected] iOS: Remove dead code/unused imports from FlutterPlatformViewsController (flutter/flutter#196084) 2026-11-06 [email protected] Replace pull_request_target workflows with pull_request + workflow_run (flutter/flutter#195536) 2026-11-06 [email protected] [master] Update Flutter DEPS to Dart 3b174b7217fe09b21da836ea623932b5f041b091 (flutter/flutter#196004) 2026-11-06 [email protected] Fix android_hardware_smoke_test retry mechanisms (flutter/flutter#195708) 2026-11-06 [email protected] Roll Skia from 452b9c1e5db6 to f533d4034900 (1 revision) (flutter/flutter#196129) 2026-11-06 [email protected] [flutter_tools] Use `ErrorHandlingFileSystem.deleteIfExists` for `IOSCoreDeviceControl` temp directory cleanup (flutter/flutter#195913) 2026-11-06 [email protected] Adds guideline tests to flutter create samples (flutter/flutter#195827) 2026-11-06 [email protected] refactor(flutter_tools): unify OptionDescriptor identity and addTo (flutter/flutter#196076) 2026-11-06 [email protected] Roll pub packages (flutter/flutter#196114) 2026-11-06 [email protected] Roll Skia from 5ce64e63a0e7 to 452b9c1e5db6 (5 revisions) (flutter/flutter#196111) 2026-11-06 [email protected] Add PlatformDispatcher.onAlwaysUse24HourFormatChanged callback (flutter/flutter#194670) 2026-11-06 [email protected] Roll Packages from 0478162 to 63881f9 (10 revisions) (flutter/flutter#196108) 2026-11-06 [email protected] Roll Skia from 793b8ac73d4b to 5ce64e63a0e7 (4 revisions) (flutter/flutter#196107) If this roll has caused a breakage, revert this CL and set the roller to dry run mode using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
This PR adds
ResizeImagePolicy.cover. With this policy,ResizeImagedecodes the image at the smallest size that covers thewidthxheightbox and keeps the aspect ratio of the image, likeBoxFit.cover.Problem
There is no resize policy that matches
BoxFit.cover. A caller that paints withBoxFit.coverand does not know the aspect ratio of the image before the decode has two options:ResizeImagePolicy.fit, or set only one ofcacheWidthandcacheHeight. For many aspect ratios, the decoded image is smaller than the box, so it is blurry when it is painted.Change
ResizeImagePolicy.cover. It requires bothwidthandheight(assert in theResizeImageconstructor).getTargetSize, so the caller does not need to know the image size.doublescale, a 3000x3000 image in a 448x256 box decodes at 449x449.)allowUpscalingis true. This is the same as thefitpolicy.ResizeImagePolicyandResizeImagedocs.Decoded sizes for a 640x360 box (physical pixels), with synthetic images:
cacheWidth: 640fit(640x360)cover(640x360)coveris the only option that fills the box in all cases without a full-size decode. On a macOS host, a 4032x3024 JPEG decodes in approximately 102 ms with no resize (48.77 MB) and approximately 46 ms withcoverinto a 200x200 box (267x200, 0.21 MB), median of 25 runs.Compatibility
This adds a value to a public enum. Code outside the framework that has a
switchonResizeImagePolicywith nodefaultgets a compile-time error (non-exhaustive switch). In this repository (packages/anddev/), onlyResizeImageitself switches onResizeImagePolicy.Tests
Added tests in
test/painting/image_provider_resize_image_test.dartfor thecoverpolicy: square, portrait, and landscape images in square, wide, and tall boxes, round-up of the other side, no extra pixel when the scale is exact, no upscaling by default, upscaling withallowUpscaling: true, and the assert whenwidthorheightis null.Fixes #61987
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.