在 Flutter 中表现 blur/opacity?

Performant blur/opacity in Flutter?

我喜欢使用 BackdropFilter 的模糊霜效果(参见 )。

但是,由于 BackdropFilter 具有不透明度,并且我正在模糊处理的小部件也具有不透明度,因此性能非常糟糕。这也是因为我每秒重绘我的小部件几次,但这应该不是问题,因为 Flutter 可以达到 60fps?

我打开了 checkerboardOffscreenLayers 并查看了英里的棋盘格。 :O 棋盘出现是由于 blurScreen,而不是由于 widgetToBlur,但 widgetToBlur 确实降低了性能,可能是因为(在我的真实代码中,不是这个例子)它每秒调用 setState() 多次.

是否有更高效的方法来制作 blurs/opacities?上面的 link 表示将不透明度单独应用于小部件。我不能用模糊来做到这一点(下面的 blurScreen),因为 BackdropFilter 必须堆叠在我的 widget-that-does-the-redrawing 之上。 我删除了模糊效果,我的表​​现更好了(没有棋盘,应用程序没有崩溃)。

build() 有问题的代码:

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'),
    ],
  ),
);

我最终使用 Paint and Canvas.

绘制了 widgetToBlur 一次,模糊,不透明

这意味着它只在 initState() 中运行一次模糊和不透明操作,并且在小部件的整个生命周期中永远不必重新渲染模糊。

如果其他人最终遇到这个问题,您可以发表评论,我可以提供更多帮助。

我有一个类似的问题,它也归结为使用 canvas 和绘画。 现在唯一的问题是,如果我将 MaskFilter 应用于图像,尽管 sigma 非常高,但不会发生太多事情......只有边缘有点模糊。

现在的问题是为什么会这样?你是怎么解决这个问题的?

canvas.drawImageRect(
  image, 
  Offset(0, 0) & srcSize, 
  Offset(-delta, 0) & dstSize, 
  Paint()..maskFilter = MaskFilter.blur(
    BlurStyle.normal, 100.0
  )
); 

有兴趣的朋友,我已经在init函数中加载了图片如下:

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。不幸的是,我还不能写任何评论;因此在这里作为贡献,包括解决方案提案

你可以用这个。但我不知道速度。

var pr = ui.PictureRecorder();
var canvas = ui.Canvas(pr);

canvas.drawImage(
        img,
        ui.Offset(0, 0),
        ui.Paint()..maskFilter = ui.MaskFilter.blur(
            BlurStyle.normal, 100.0
        )
    );

var pic = pr.endRecording();
return pic.toImage(img.width, img.height);