国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android 實(shí)現(xiàn)高斯模糊效果且兼容低版本

2019-12-12 05:11:21
字體:
供稿:網(wǎng)友

 一、效果演示

項(xiàng)目中用到了高斯模糊效果,查閱過一些資料,考慮到性能問題最終還是選擇使用Android自帶的RenderScript庫來實(shí)現(xiàn),關(guān)于使用RenderScript來實(shí)現(xiàn)高斯模糊網(wǎng)上也有很多類似的方法,大部分都總結(jié)的比較亂,此處算是做一個(gè)整理吧,供有類似需求的同學(xué)參考及學(xué)習(xí)。



(項(xiàng)目效果圖)

簡(jiǎn)單描述項(xiàng)目效果圖的實(shí)現(xiàn)思路:

① 加載定義的xml的Layout

② 使用截屏方法獲取當(dāng)前窗口的Bitmap對(duì)象

③ 將Bitmap對(duì)象進(jìn)行壓縮及高斯模糊處理

④ 將處理過的模糊圖對(duì)象作為①中所加載出來的Layout的Background

⑤ 將已經(jīng)加入了模糊圖對(duì)象的Layout添加到PopuWindow中并處理子條目的彈出方式

二、適用RenderScript實(shí)現(xiàn)高斯模糊

實(shí)現(xiàn)高斯模糊效果的方法有很多,可以用java來實(shí)現(xiàn),可以使用NDK來實(shí)現(xiàn),也可以使用本文推薦的方式來實(shí)現(xiàn)(也是使用了JNI的方式),至于為什么選擇使用RenderScript方式來實(shí)現(xiàn),必然有一定優(yōu)點(diǎn)。

優(yōu)點(diǎn):RenderScript方式,速度極快,約為java方式100倍的速度,NDK方式20倍速度(不同圖片質(zhì)量測(cè)試所得結(jié)果不同,供參考)

缺點(diǎn):API17以上有效。(但Google已提供向下兼容的方法,文章后面會(huì)有介紹)

下面是使用RenderScript方式的核心代碼:

/************************ * 高斯模糊處理 * @param bitmap * @param context * @return ***********************/ public static Bitmap blurBitmap(Bitmap bitmap, Context context) { // 用需要?jiǎng)?chuàng)建高斯模糊bitmap創(chuàng)建一個(gè)空的bitmap Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); // 初始化Renderscript,該類提供了RenderScript context,創(chuàng)建其他RS類之前必須先創(chuàng)建這個(gè)類,其控制RenderScript的初始化,資源管理及釋放 RenderScript rs = RenderScript.create(context); // 創(chuàng)建高斯模糊對(duì)象 ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); // 創(chuàng)建Allocations,此類是將數(shù)據(jù)傳遞給RenderScript內(nèi)核的主要方法,并制定一個(gè)后備類型存儲(chǔ)給定類型 Allocation allIn = Allocation.createFromBitmap(rs, bitmap); Allocation allOut = Allocation.createFromBitmap(rs, outBitmap); //設(shè)定模糊度(注:Radius最大只能設(shè)置25.f) blurScript.setRadius(15.f); // Perform the Renderscript blurScript.setInput(allIn); blurScript.forEach(allOut); // Copy the final bitmap created by the out Allocation to the outBitmap allOut.copyTo(outBitmap); // recycle the original bitmap bitmap.recycle(); // After finishing everything, we destroy the Renderscript. rs.destroy(); return outBitmap; }

該方法中注釋描述的很清楚,但需要注意的是blurScript.setRadius();方法,該方法設(shè)定模糊度時(shí)Radius最大只能設(shè)置25.f,可能是對(duì)圖片直接進(jìn)行處理會(huì)導(dǎo)致模糊效果不好,故此值最大有效設(shè)定為25,但若想實(shí)現(xiàn)更深度的模糊效果,可以先壓縮圖片,降低圖片的質(zhì)量來實(shí)現(xiàn)更模糊的效果。

下方是圖片的壓縮處理方法:

/** * Compress image by pixel, this will modify image width/height. * * @param imgPath image path * @param pixelW target pixel of width * @param pixelH target pixel of height * @return */ public static Bitmap ratio(String imgPath, float pixelW, float pixelH) { BitmapFactory.Options newOpts = new BitmapFactory.Options(); // 開始讀入圖片,此時(shí)把options.inJustDecodeBounds 設(shè)回true,即只讀邊不讀內(nèi)容 newOpts.inJustDecodeBounds = true; newOpts.inPreferredConfig = Config.RGB_565; // Get bitmap info, but notice that bitmap is null now Bitmap bitmap = BitmapFactory.decodeFile(imgPath,newOpts); newOpts.inJustDecodeBounds = false; int w = newOpts.outWidth; int h = newOpts.outHeight; float ww = pixelW; //設(shè)置寬度為120f,可以明顯看到圖片縮小了 float hh = pixelH; //設(shè)置高度為240f時(shí),可以明顯看到圖片縮小了 //縮放比,由于是固定比例縮放,只用高或者寬其中一個(gè)數(shù)據(jù)進(jìn)行計(jì)算即可 int be = 1;//表示不縮放 if (w > h && w > ww) { //如果寬度大的話根據(jù)寬度固定大小縮放 be = (int) (newOpts.outWidth / ww); } else if (w < h && h > hh) { //如果高度高的話根據(jù)寬度固定大小縮放 be = (int) (newOpts.outHeight / hh); } if (be <= 0) be = 1; newOpts.inSampleSize = be;//設(shè)置縮放比例 // 開始?jí)嚎s圖片,注意此時(shí)已經(jīng)把options.inJustDecodeBounds 設(shè)回false了 bitmap = BitmapFactory.decodeFile(imgPath, newOpts); // 壓縮好比例大小后再進(jìn)行質(zhì)量壓縮 //return compress(bitmap, maxSize); //這里再進(jìn)行質(zhì)量壓縮的意義不大,反而耗資源,刪除 return bitmap; } 

以上方法是使用RenderScript來實(shí)現(xiàn)高斯模糊的核心代碼塊及需注意的地方。但是,還是需要注意兼容問題,上述有提到該方法僅適用于API17以上才有效,那么問題來了,需要處理API向下兼容問題。

三、處理API向下兼容問題及注意點(diǎn)

在按照上述方法實(shí)現(xiàn)高斯模糊后,運(yùn)行一看效果,滿滿的成就感,此時(shí),Boss正好帶著客戶過來,小伙子,來,幫客戶安裝一個(gè)最新的版本(客戶手機(jī)系統(tǒng)版本為Android4.0),裝完后一點(diǎn)。。。。。。。。。。。這特么就尷尬了…………!

追蹤bug時(shí)有同學(xué)可能會(huì)出現(xiàn)如下錯(cuò)誤信息:

異常信息一:

09-21 15:07:34.417: E/AndroidRuntime(4476): android.support.v8.renderscript.RSRuntimeException: Error loading RS jni library: java.lang.UnsatisfiedLinkError: Couldn't load RSSupport: findLibrary returned null………………

異常信息二:

java.lang.NoClassDefFoundError: android.renderscript.ScriptIntrinsicBlur………………

解決方案:

報(bào)錯(cuò)信息為android.support.v8.renderscript.RSRuntimeException: Error loading 以及 java.lang.UnsatisfiedLinkError: Couldn't load RSSupport from loader dalvik.system.PathClassLoader 是由于在4.2以上的手機(jī)自帶 librsjni.so和libRSSupport.so庫,而4.2以下某些手機(jī)沒有這兩個(gè)jni庫。所以得把這兩個(gè)jni 導(dǎo)入到我們的工程下便可。那么文件在何處呢?

以下是本人的文件路徑:C:/Tools/android-sdk/build-tools/23.0.3/renderscript/lib/packaged,renderscript-v8.jar包位于renderscript/lib目錄下。

即:android sdk 路徑下 build-tools/各個(gè)版本/renderscript/lib/packaged 下的四個(gè)目錄,這里需要注意jar包和.so版本的選擇最好選最新的,例如24.0.0中增加了x86-64的適配。

好了,到這里就可以完美的兼容4.2以下的版本了。另外,還有一個(gè)最最最重要的注意點(diǎn),我被這個(gè)細(xì)節(jié)困擾了至少2小時(shí),現(xiàn)在想起來還覺得蛋疼,在你做完上面的一切事情之后,請(qǐng)注意一定能要將import的包路徑更換過來:import android.renderscript更換為import android.support.v8.renderscript。具體如下:

import android.support.v8.renderscript.Allocation; import android.support.v8.renderscript.Element; import android.support.v8.renderscript.RenderScript; import android.support.v8.renderscript.ScriptIntrinsicBlur; 

最最最最后需要注意的一點(diǎn),若項(xiàng)目中對(duì)代碼加了混淆,別忘了這個(gè)。OK,就到這里了。

四、附:

另外分享兩個(gè)處理高斯模糊的GitHub:

https://github.com/wl9739/BlurredView
https://github.com/robinxdroid/Blur

以上所述是小編給大家介紹的Android 實(shí)現(xiàn)高斯模糊效果且兼容低版本的全部敘述,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)武林網(wǎng)網(wǎng)站的支持!

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 班玛县| 龙江县| 佳木斯市| 张家界市| 宁国市| 淳安县| 浙江省| 麻城市| 泾川县| 泊头市| 温州市| 景德镇市| 枞阳县| 武平县| 达孜县| 图木舒克市| 马龙县| 瑞安市| 板桥市| 龙州县| 根河市| 托里县| 周宁县| 万山特区| 苍溪县| 郯城县| 定日县| 平谷区| 南乐县| 南漳县| 定结县| 宾川县| 紫阳县| 斗六市| 通江县| 古浪县| 西丰县| 云浮市| 陆川县| 武乡县| 潍坊市|