Repository navigation
centerSlice throws exception when scaling down #27827
Description
This seems closely related to #20013, but I'm not sure whether it is the same issue.
I have two images that are being used as resolution-aware assets: the "main" asset is 68x46, and the 3.0x pixel ratio version is 208x142. If I use the asset in an Image widget with no centerSlice it works fine -- the 3.0x version is rendered at the same size as the lower-res main image as expected. I can set the width and height properties and they work as well.
Next, if I include only the main asset and give it a centerSlice and set the size of the Image to 100x46 everything still works okay, the centerSlice is applied properly, and everything looks good.
However, as soon as I add the 3.0x version, Flutter fails an assertion and throws an error about the BoxFit being wrong (even though it isn't) and says to create an issue here.
It seems the problem is something to do with the centerSlice processing not handling the scaling correctly. The only way I can make the error go away is to set the height and width of the Image to something that is equal to or greater than the actual size of the 3.0x image. Of course, that is not an actual solution because then the image renders at that larger size instead of what it should be.
Logs
I/flutter (10662): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter (10662): The following assertion was thrown during paint():
I/flutter (10662): centerSlice was used with a BoxFit that does not guarantee that the image is fully
visible.
I/flutter (10662): 'package:flutter/src/painting/decoration_image.dart': Failed assertion: line 406 pos 12: 'sourceSize
I/flutter (10662): == inputSize'
I/flutter (10662):
I/flutter (10662): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter (10662): more information in this error message to help you determine and fix the underlying cause.
I/flutter (10662): In either case, please report this assertion by filing a bug on GitHub:
I/flutter (10662): https://github.com/flutter/flutter/issues/new?template=BUG.md
I/flutter (10662):
I/flutter (10662): When the exception was thrown, this was the stack:
I/flutter (10662): #2 paintImage (package:flutter/src/painting/decoration_image.dart:406:12)
I/flutter (10662): #3 RenderImage.paint (package:flutter/src/rendering/image.dart:357:5)
I/flutter (10662): #4 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2094:7)
I/flutter (10662): #5 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:173:13)
I/flutter (10662): #6 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:122:15)
I/flutter (10662): #7 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2094:7)
I/flutter (10662): #8 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:173:13)
I/flutter (10662): #9 _RenderFlex&RenderBox&ContainerRenderObjectMixin&RenderBoxContainerDefaultsMixin.defaultPaint (package:flutter/src/rendering/box.dart:2273:15)
I/flutter (10662): #10 RenderFlex.paint (package:flutter/src/rendering/flex.dart:931:7)
I/flutter (10662): #11 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2094:7)
I/flutter (10662): #12 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:173:13)
I/flutter (10662): #13 RenderShiftedBox.paint (package:flutter/src/rendering/shifted_box.dart:70:15)
I/flutter (10662): #14 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2094:7)
I/flutter (10662): #15 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:173:13)
I/flutter (10662): #16 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:122:15)
I/flutter (10662): #17 RenderDecoratedBox.paint (package:flutter/src/rendering/proxy_box.dart:1974:11)
I/flutter (10662): #18 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2094:7)
I/flutter (10662): #19 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:173:13)
I/flutter (10662): #20 RenderShiftedBox.paint (package:flutter/src/rendering/shifted_box.dart:70:15)
I/flutter (10662): #21 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2094:7)
I/flutter (10662): #22 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:173:13)
I/flutter (10662): #23 _RenderCustomMultiChildLayoutBox&RenderBox&ContainerRenderObjectMixin&RenderBoxContainerDefaultsMixin.defaultPaint (package:flutter/src/rendering/box.dart:2273:15)
I/flutter (10662): #24 RenderCustomMultiChildLayoutBox.paint (package:flutter/src/rendering/custom_layout.dart:361:5)
I/flutter (10662): #25 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2094:7)
I/flutter (10662): #26 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:173:13)
I/flutter (10662): #27 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:122:15)
I/flutter (10662): #28 _RenderInkFeatures.paint (package:flutter/src/material/material.dart:491:11)
I/flutter (10662): #29 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2094:7)
I/flutter (10662): #30 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:173:13)
I/flutter (10662): #31 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:122:15)
I/flutter (10662): #32 RenderPhysicalModel.paint.<anonymous closure> (package:flutter/src/rendering/proxy_box.dart:1724:88)
I/flutter (10662): #33 ClipContext._clipAndPaint (package:flutter/src/painting/clip.dart:29:12)
I/flutter (10662): #34 ClipContext.clipRRectAndPaint (package:flutter/src/painting/clip.dart:49:5)I/flutter (10662): #35 RenderPhysicalModel.paint (package:flutter/src/rendering/proxy_box.dart:1724:17)
I/flutter (10662): #36 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2094:7)
I/flutter (10662): #37 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:173:13)
I/flutter (10662): #38 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:122:15)
I/flutter (10662): #39 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2094:7)
I/flutter (10662): #40 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:173:13)
I/flutter (10662): #41 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:122:15)
I/flutter (10662): #42 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2094:7)
I/flutter (10662): #43 PaintingContext._repaintCompositedChild (package:flutter/src/rendering/object.dart:128:11)
I/flutter (10662): #44 PaintingContext.repaintCompositedChild (package:flutter/src/rendering/object.dart:96:5)
I/flutter (10662): #45 PipelineOwner.flushPaint (package:flutter/src/rendering/object.dart:855:29)I/flutter (10662): #46 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:283:19)
I/flutter (10662): #47 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:686:13)
I/flutter (10662): #48 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:219:5)
I/flutter (10662): #49 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15)
I/flutter (10662): #50 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9)
I/flutter (10662): #51 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:842:5)
I/flutter (10662): #52 _invoke (dart:ui/hooks.dart:159:13)
I/flutter (10662): #53 _drawFrame (dart:ui/hooks.dart:148:3)
I/flutter (10662): (elided 2 frames from class _AssertionError)
I/flutter (10662):
I/flutter (10662): The following RenderObject was being processed when the exception was fired:
I/flutter (10662): RenderImage#77fd3 relayoutBoundary=up6
I/flutter (10662): creator: RawImage ← Semantics ← Image ← GoogleSignInButton ← BlocBuilder<AccountEvent,
I/flutter (10662): AccountState> ← Column ← Padding ← DecoratedBox ← Container ← MediaQuery ← Padding ← SafeArea ← ⋯
I/flutter (10662): parentData: <none> (can use size)
I/flutter (10662): constraints: BoxConstraints(0.0<=w<=395.4, 0.0<=h<=Infinity)
I/flutter (10662): size: Size(69.3, 47.3)
I/flutter (10662): image: [208×142]
I/flutter (10662): scale: 3.0
I/flutter (10662): alignment: center
I/flutter (10662): centerSlice: Rect.fromLTRB(53.0, 7.0, 55.0, 9.0)
I/flutter (10662): invertColors: false
I/flutter (10662): filterQuality: low
I/flutter (10662): This RenderObject has no descendants.
I/flutter (10662): ════════════════════════════════════════════════════════════════════════════════════════════════════
No issues found! (ran in 21.0s)
[√] Flutter (Channel beta, v1.1.8, on Microsoft Windows [Version 10.0.17763.55], locale en-US)
• Flutter version 1.1.8 at C:\Users\Caleb\flutter
• Framework revision 985ccb6d14 (5 weeks ago), 2019-01-08 13:45:55 -0800
• Engine revision 7112b72cc2
• Dart version 2.1.1 (build 2.1.1-dev.0.1 ec86471ccc)
[!] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
• Android SDK at C:\Users\Caleb\AppData\Local\Android\sdk
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-28, build-tools 28.0.3
• Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1248-b01)
X Android license status unknown.
[√] Android Studio (version 3.3)
• Android Studio at C:\Program Files\Android\Android Studio
• Flutter plugin version 32.0.1
• Dart plugin version 182.5124
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1248-b01)
[√] VS Code (version 1.31.0)
• VS Code at C:\Users\Caleb\AppData\Local\Programs\Microsoft VS Code
• Flutter extension version 2.22.3
[√] Connected device (1 available)
• Pixel 2 XL • 709KPNY0046767 • android-arm64 • Android 9 (API 28)
! Doctor found issues in 1 category.
Activity
zoechi commentedon Feb 12, 2019
To investigate we would need a minimal runnable reproduction
ideally published as a GitHub repo.
Herohtar commentedon Feb 13, 2019
@zoechi Sure. I didn't have time to put one together until this evening, but here you go: https://github.com/Herohtar/center_slice
I've included a screenshot of the main window as well as the exception thrown by Flutter from this code. The higher resolution image is a different color to show that it is being picked up by Flutter as intended.
As an additional note, you can get rid of the exception by setting the
heightto 79 or higher (the actual height of the higher-res image is 80). However, that makes it impossible to use resolution-aware images withcenterSlicein cases where the desired dimensions are less than the auto-selected image.Herohtar commentedon Feb 19, 2019
After looking into this a bit more, it seems this isn't really about resolution-aware images at all. The problem is that Flutter throws an error if either the destination
heightorwidthare less than the corresponding dimension in the source image and thecenterSliceis proportionately small. For example, with the 40x40 source image, if I try to usecenterSlice: Rect.fromLTRB(19, 19, 21, 21)withheight: 30it will fail. Alternatively,centerSlice: Rect.fromLTRB(5, 5, 35, 35)works fine with the same height (30).I believe the root of the problem is within this section of the image drawing function:
flutter/packages/flutter/lib/src/painting/decoration_image.dart
Lines 385 to 407 in 7aeb539
Specifically, when
centerSlicedefines a very small center rectangle it will result in a largesliceBorder. Then, when any part of theoutputSizeis smaller than theinputSize, the followingoutputSize -= sliceBorderwill result in some negative values, which are then fed intoapplyBoxFit, which immediately spits out all zeros for bothsourceanddestination. Obviously, since zero doesn't match the initial input size, the assert fails.This problem seems to come from the (mistaken) idea that the corners of
centerSlice'd images are never scaled, as the comments state that the corner pieces are drawn without scaling; however, the documentation for the underlying drawImageNine function indicates that scaling down is a potential valid behavior:I'm not entirely certain how this needs to be modified, but it seems it needs to allow for scaling down when using
centerSlice, and also will need to take thescaleinto account so that resolution-aware images are handled properly, as I believe there is still an issue with that.[-]centerSlice throws exception when using resolution-aware images[/-][+]centerSlice throws exception when scaling down[/+]welstone commentedon May 21, 2019
I found the problem too; As we can see, centerSlice's unit is 'px', but outputSize's unit is 'dp'; How do you think if we re-calculate the centerSlice according to 'scale', and pass new value of centerSlice to canvas;
welstone commentedon May 21, 2019
Or can we just remove such codes:
As mentioned in the issue:
#20013
I also made the same test, if sliceBorder related codes were removed, all works fine
welstone commentedon May 21, 2019
Furthermore, On line: 393
https://github.com/flutter/flutter/blob/beta/packages/flutter/lib/src/painting/decoration_image.dart
outputSize was reduced by sliceBorder;
but on line :402 , outputSize was restored again, with nothing changed
After 'applyBoxFit(fit, inputSize / scale, outputSize)' , destinationSize == outputSize and sourceSize == inputSize because 'fit == BoxFit.fill'
After line 407, destinationSize was restored to 'rect.size' again (line: 385)
So I think, line 393, 394, 402,403, 406 are useless, and we should remove all of them;
Forget about my poor English :)
goderbauer commentedon Mar 18, 2020
/cc @dnfield FYI for image related stuff.
19 remaining items
Stumblinbear commentedon Jul 31, 2025
Sundin commentedon Aug 4, 2025
shang1219178163 commentedon Apr 20, 2026
I'm not sure if it solves everyone's problem, but my code works fine.
Avoid centerSlice assertion failure under floating-point rounding
Avoid centerSlice assertion failure under floating-point rounding
Avoid centerSlice assertion failure under floating-point rounding
Avoid centerSlice assertion failure under floating-point rounding
Avoid centerSlice assertion failure under floating-point rounding
Avoid centerSlice assertion failure under floating-point rounding
Avoid centerSlice assertion failure under floating-point rounding
Avoid centerSlice assertion failure under floating-point rounding
Tolerate floating-point rounding in paintImage centerSlice assertion (f…
github-actions commentedon Sep 9, 2026
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.