利用Flutter實(shí)現(xiàn)背景圖片毛玻璃效果實(shí)例
前言
繼續(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ù)說明如下:
image
:dart: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 thedst
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)和我們上兩篇使用 paint
的 shader
屬性有點(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)模糊效果,有興趣的可以自行百度一下。下面的 sigmaX
和 sigmaY
分布代表橫軸方向和縱軸方向的模糊程度,數(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)文章
Android 使用fast-verification實(shí)現(xiàn)驗(yàn)證碼填寫功能的實(shí)例代碼
這篇文章主要介紹了Android 使用fast-verification實(shí)現(xiàn)驗(yàn)證碼填寫功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04Android自定義PopupWindow仿點(diǎn)擊彈出分享功能
這篇文章主要為大家詳細(xì)介紹了Android自定義PopupWindow仿點(diǎn)擊彈出分享功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02Android實(shí)現(xiàn)可點(diǎn)擊的幸運(yùn)大轉(zhuǎn)盤
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)可點(diǎn)擊的幸運(yùn)大轉(zhuǎn)盤,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02全面解析Android中對(duì)EditText輸入實(shí)現(xiàn)監(jiān)聽的方法
這篇文章主要介紹了Android中對(duì)EditText輸入實(shí)現(xiàn)監(jiān)聽的方法,包括一個(gè)仿iOS的帶清除功能的ClearEditText輸入框控件的詳細(xì)使用介紹,需要的朋友可以參考下2016-04-04Android實(shí)現(xiàn)百度地圖兩點(diǎn)畫弧線
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)百度地圖兩點(diǎn)畫弧線,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01Android中實(shí)現(xiàn)根據(jù)資源名獲取資源ID
這篇文章主要介紹了Android中實(shí)現(xiàn)根據(jù)資源名獲取資源ID,本文講解了使用文件名獲取資源ID的方法,需要的朋友可以參考下2015-01-01