欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

利用Flutter實(shí)現(xiàn)背景圖片毛玻璃效果實(shí)例

 更新時(shí)間:2022年06月26日 08:19:11   作者:島上碼農(nóng)  
Flutter沒有單獨(dú)的模糊處理容器,需要部件層層疊加實(shí)現(xiàn)模糊效果,下面這篇文章主要給大家介紹了關(guān)于利用Flutter實(shí)現(xiàn)背景圖片毛玻璃效果的相關(guān)資料,需要的朋友可以參考下

前言

繼續(xù)我們繪圖相關(guān)篇章,這次我們來看看如何使用 CustomPaint 實(shí)現(xiàn)毛玻璃背景圖效果。毛玻璃背景圖其實(shí)就是將圖片進(jìn)行一定程度的模糊,背景圖經(jīng)過模糊后更加虛幻,使得前景和后景就會(huì)有層次感。相比直接加蒙層的效果來說,毛玻璃看起來更加好看一些。下面是背景圖處理前后的對(duì)比,我們的前景圖片的透明度并沒有改變,但是背景圖模糊虛化后,感覺前景更加顯眼了一樣。

本篇涉及如下內(nèi)容:

  • 使用 canvas 繪制圖片。
  • 繪制圖片時(shí)如何更改圖片的填充范圍。
  • 使用 ImageFilter 模糊圖片,實(shí)現(xiàn)毛玻璃效果。

使用 canvas 繪制圖片

Flutter 為 canvas 提供了drawImage 方法用于繪制圖片,方法定義如下:

void drawImage(Image image, Offset offset, Paint paint)

其中各個(gè)參數(shù)說明如下:

  • imagedart:ui 中的 Image 對(duì)象,注意不是Widget 中的 Image,因此繪制的時(shí)候需要將圖片資源轉(zhuǎn)換為 ui.Image 對(duì)象。下面是轉(zhuǎn)換的示例代碼,fillImage 即最終得到的 ui.Image 對(duì)象。注意轉(zhuǎn)換需要一定的時(shí)間,因此需要使用異步 async / await 操作。
Future<void> init() async {
  final ByteData data = await rootBundle.load('images/island-coder.png');
  fillImage = await loadImage(Uint8List.view(data.buffer));
}

Future<ui.Image> loadImage(Uint8List img) async {
  final Completer<ui.Image> completer = Completer();
  ui.decodeImageFromList(img, (ui.Image img) {
    setState(() {
      isImageLoaded = true;
    });
    return completer.complete(img);
  });
  return completer.future;
}
  • offset:繪制圖片的起始位置。
  • paint:繪圖畫筆對(duì)象,在 paint 上可以應(yīng)用各種處理效果,比如本篇要用到的圖片模糊效果。

注意,drawImage 方法無法更改圖片繪制的區(qū)域大小,默認(rèn)就是按圖片的實(shí)際尺寸繪制的,所以如果要想保證全屏的背景圖,我們就需要使用另一個(gè)繪制圖片的方法。

更改繪制圖片的繪制范圍

Flutter 的 canvas 為繪制圖片提供了一個(gè)尺寸轉(zhuǎn)換方法,即可以通過指定原繪制區(qū)域的矩形和目標(biāo)區(qū)域的矩形,將圖片某個(gè)區(qū)域映射到新的矩形框中繪制。也就是我們甚至可以實(shí)現(xiàn)繪制圖片的局部區(qū)域。該方法名為 drawImageRect,定義如下:

void drawImageRect(Image image, Rect src, Rect dst, Paint paint)

方法的參數(shù)比較容易懂,我們來看看 Flutter 的文檔說明。

Draws the subset of the given image described by the src argument into the canvas in the axis-aligned rectangle given by the dst argument. 翻譯:通過 src 參數(shù)將給定圖片的局部(subset)繪制到坐標(biāo)軸對(duì)齊的目標(biāo)矩形區(qū)域內(nèi)。

下面是我們將源矩形框設(shè)置為實(shí)際圖片的尺寸和一半寬高的對(duì)比圖,可以看到取一半寬高的只繪制了左上角的1/4區(qū)域。實(shí)際我們可以定位起始位置來截取部分區(qū)域繪制。

毛玻璃效果實(shí)現(xiàn)

毛玻璃效果實(shí)現(xiàn)和我們上兩篇使用 paintshader屬性有點(diǎn)類似,Paint 類提供了一個(gè)imageFilter屬性專門用于圖片處理,其中dart:ui 中就提供了ui.ImageFilter.blur方法構(gòu)建模糊效果處理的 ImageFilter對(duì)象。方法定義如下:

factory ImageFilter.blur({ 
  double sigmaX = 0.0, 
  double sigmaY = 0.0, 
  TileMode tileMode = TileMode.clamp 
})

這個(gè)方法實(shí)際調(diào)用的是一個(gè)高斯模糊處理器,高斯模糊其實(shí)就是應(yīng)用一個(gè)方法將像素點(diǎn)周邊指定范圍的值進(jìn)行處理,進(jìn)而實(shí)現(xiàn)模糊效果,有興趣的可以自行百度一下。下面的 sigmaXsigmaY 分布代表橫軸方向和縱軸方向的模糊程度,數(shù)值越大,模糊程度越厲害。因此我們可以通過這兩個(gè)參數(shù)控制模糊程度。

return _GaussianBlurImageFilter(
  sigmaX: sigmaX, 
  sigmaY: sigmaY, 
  tileMode: tileMode
);

**注意,這里 sigmaX 和 sigmaY 不能同時(shí)為0,否則會(huì)報(bào)錯(cuò)!**這里應(yīng)該是如果同時(shí)為0會(huì)導(dǎo)致除0操作。 下面來看整體的繪制實(shí)現(xiàn)代碼,如下所示:

class BlurImagePainter extends CustomPainter {
  final ui.Image bgImage;
  final double blur;

  BlurImagePainter({
    required this.bgImage,
    required this.blur,
  });
  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint();
    // 模糊的取值不能為0,為0會(huì)拋異常
    if (blur > 0) {
      paint.imageFilter = ui.ImageFilter.blur(
        sigmaX: blur,
        sigmaY: blur,
        tileMode: TileMode.mirror,
      );
    }

    canvas.drawImageRect(
      bgImage,
      Rect.fromLTRB(0, 0, bgImage.width.toDouble(), bgImage.height.toDouble()),
      Offset.zero & size,
      paint,
    );
  }

代碼其實(shí)很短,就是在模糊值不為0的時(shí)候,應(yīng)用 imageFilter 進(jìn)行模糊處理,然后使用 drawImageRect 方法確保圖片填充滿整個(gè)背景。完整代碼已經(jīng)提交至:繪圖相關(guān)代碼,文件名為:blur_image_demo.dart。變換模糊值的效果如下動(dòng)圖所示。

總結(jié)

本篇介紹了使用 CustomPaint 實(shí)現(xiàn)背景圖模糊,毛玻璃的效果。關(guān)鍵點(diǎn)在于 使用 Paint 對(duì)象的 imageFilter屬性,使用高斯模糊應(yīng)用到圖片上。以后碰到需要模糊背景圖的地方就可以直接上手用啦!

到此這篇關(guān)于利用Flutter實(shí)現(xiàn)背景圖片毛玻璃效果的文章就介紹到這了,更多相關(guān)Flutter背景圖片毛玻璃內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論