Reputation: 21
I am trying to create a simple container widget that has rounded corners and a blurred background image. However the BackdropFilter and ImageFilter.blur() reacts poorly with creating a widget blurred to the edges. I am getting color bleed through the blur from the background color(s).
I have tried many different implementations and public blur libraries, but have not been able to get it to work. Most times the corners are still letting light bleed in.
This is in figma where I scaled the image and clipped to remove the blur:
This is what I am able to do in flutter and it has clear color bleed:
I'm unsure why I cannot just apply the blur to the image only and clip off the ends like I did in figma. It seems like such an oversight on flutters side. We landed on the moon in 69' but I can't crop a blurred image 60 years later.
return Scaffold(
backgroundColor: Colors.red,
body: Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(11),
child: Stack(
alignment: Alignment.center,
children: [
Container(
height: 174,
width: 289,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/temp_images/The_Marias.jpeg'),
fit: BoxFit.cover)),
),
ClipRRect(
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
child: const SizedBox(
height: 174,
width: 289,
),
),
),
],
),
),
),
);
}
I've tried every sort of stack, transform, clipping, etc I could think of and still get the same result. Could use any help or recommendations possible.
Tried blurring a background image of a container that needs a border radius. Color bleed is being applied to the blur instead of a clean mask.
Upvotes: 2
Views: 176
Reputation: 31386
BackdropFilter will take a snapshot of everything that was drawn on the screen before the child widget as one piece, so the red background is also going to be blurred, which means the red color will be merged into the image. By applying the ClipRRect, the order of operations is Blur and then Clip, so you will always have the red portion mixed with final result.
There is an open issue to allow changing this order: https://github.com/flutter/flutter/issues/154801
Assuming you just want to blur the Image, you don't have to use the BackdropFilter widget. You just need an ImageFiltered widget, which is also cheaper. Also, check the tileMode to be mirror or repeated.
class BlurredImageDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.red,
body: Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(11),
child: Stack(
alignment: Alignment.center,
children: [
ImageFiltered(
imageFilter: ImageFilter.blur(
sigmaX: 25,
sigmaY: 25,
tileMode: TileMode.mirror,
),
child: Container(
height: 200,
width: 300,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(11),
image: DecorationImage(
image: NetworkImage('https://picsum.photos/id/237/300/200'),
fit: BoxFit.cover,
),
),
),
),
],
),
),
),
);
}
}
This should look like this:
Upvotes: 1
Reputation: 170
Instead of a decoration image try using normal Image.asset widget.
Scaffold(
backgroundColor: Colors.red,
body: Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(11),
child: Stack(
children: [
Image.asset(
AppConstants.placeholderAsset,
height: 174,
width: 289,
fit: BoxFit.cover,
),
BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 10,
sigmaY: 10,
),
child: const SizedBox(
height: 174,
width: 289,
),
),
],
),
),
),
);
Upvotes: 0