Performant blur/opacity in Flutter?
Solution 1
I ended up drawing the widgetToBlur once, blurred, with opacity, using Paint and Canvas.
This means it only runs the blur and opacity operations once, in initState()
, and never has to be re-rendered-with-blur throughout the lifecycle of the widget.
If anyone else ends up stuck with this, you can leave a comment and I can help out more.
Solution 2
I have a similar problem and it also boils down to using canvas and paint. The only problem now is, if I apply a MaskFilter to the image, not much happens despite the enormously high sigma... Only the edge is a little blurred.
Now the question is why is that so? How did you solved this issue?
canvas.drawImageRect(
image,
Offset(0, 0) & srcSize,
Offset(-delta, 0) & dstSize,
Paint()..maskFilter = MaskFilter.blur(
BlurStyle.normal, 100.0
)
);
For those of you who are interested, I have loaded the image in the init function as follows:
rootBundle.load("assets/gift_1.png").then((bd) {
Uint8List lst = new Uint8List.view(bd.buffer);
Ui.instantiateImageCodec(lst).then((codec) {
codec.getNextFrame().then((frameInfo) {
image = frameInfo.image;
});
});
});
P.s. Unfortunately, I can't write any comments yet; therefore here as a contribution, including solution proposal
Mary
Updated on December 07, 2022Comments
-
Mary over 1 year
I love the blurry frost effect using a BackdropFilter (see this).
However, because the BackdropFilter has Opacity and because the widget I'm blurring also has Opacity, the performance is horrendous. This is also because I redraw my widgets a few times a second, but that shouldn't be an issue given Flutter can go 60fps?
I turned on checkerboardOffscreenLayers and see checkerboards for miles. :O The checkerboards happen due to
blurScreen
, not due towidgetToBlur
butwidgetToBlur
does slow down performance probably because (in my real code, not this example) it's calling setState() multiple times a second.Is there a more performant way to make blurs/opacities? The link above says to apply opacity to widgets individually. I can't do that with the blur though (
blurScreen
below), because the BackdropFilter has to be stacked on top of my widget-that-does-the-redrawing. I removed the blur effect and my performance is way better (no checkerboards, app doesn't crash).build() code in question:
final widgetToBlur = Container( child: Opacity( opacity: 0.3, // In my actual code, this is a Stateful widget. child: Text('Spooky blurry semi-transparent text!'), ), ); final blurScreen = BackdropFilter( filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0), child: Container( decoration: BoxDecoration( color: _backgroundColor.withOpacity(0.3), ), ), ); return Container( child: Stack( children: <Widget>[ widgetToBlur, blurScreen, Text('This is in front of the blurred background'), ], ), );
-
Mary over 5 yearsMy sigma was only 3. When I was playing around with MaskFilter it seemed like I needed to give it more space than the object I'm blurring, and the object needs to be centered. E.g. if your image is 100 x 100, try making your canvas size 200 x 200 and starting your image at (50, 50). This will give the outline of the blur some space. Maybe also try without any offsets, or try just drawing and blurring a solid colored rectangle first.
-
bshears over 4 yearsHi Mary, I stuck with this. I'm not sure how should I apply blur using Paint/Canvas. I'd appreciate some tips.
-
Mary over 4 yearsWhat are you stuck with? May be worthwhile to post a separate question with a code snippet.
-
bshears over 4 yearsI tried using
CustomPaint
with a few simple examples. But still I have no idea how to apply blur effect to what it's displayed on the screen with use of Paint/Canvas. -
Mary over 4 yearsDoes
maskFilter.blur()
change anything?