成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Android 上的 高斯模糊 依我之見(jiàn)

CODING / 3038人閱讀

摘要:今天就來(lái)研究一下如何在上實(shí)現(xiàn)高斯模糊效果。平時(shí)我們對(duì)圖片縮小,必然會(huì)帶來(lái)很明顯的清晰度的損失,但高斯模糊本身的目的就是要實(shí)現(xiàn)模糊的效果,因此實(shí)際上的效果差別不大,幾乎可以忽略。

前言

iOS 7 開(kāi)始 Apple 從 擬物化 過(guò)渡到了 扁平化 的設(shè)計(jì)風(fēng)格,同時(shí)也搭配使用了 毛玻璃風(fēng)格 當(dāng)做背景效果,不得不說(shuō)十分驚艷,頗有當(dāng)時(shí)pc上 Widows VistaOS X Yosemite 的味道,在那之后,Google 也從 Android L(5.0)開(kāi)始使用了 原質(zhì)化設(shè)計(jì)(Material Design) 設(shè)計(jì)語(yǔ)言,與 Microsoft 的 Metro 那種純扁平化風(fēng)格看似很相像,但實(shí)則因?yàn)橐昧?Z軸 的概念,使其有了陰影和立體感,傳達(dá)了 響應(yīng)式交互 的設(shè)計(jì)理念。說(shuō)到這里有一些跑題,因?yàn)楣P者對(duì)設(shè)計(jì)美學(xué)很感興趣,所以對(duì)這些平臺(tái)都稍微了解一些皮毛。今天就來(lái)研究一下如何在 Android 上實(shí)現(xiàn)高斯模糊效果。

目前 Android 上實(shí)現(xiàn)高斯模糊效果的方式有:

Java : FastBlur.java ,應(yīng)用非常廣泛的 StackBlur 模糊算法實(shí)現(xiàn)代碼,效率最低

C++ :兩種實(shí)現(xiàn),1:標(biāo)準(zhǔn)高斯模糊算法 2:均值模糊,效率中等

Android : RenderScript ,用來(lái)在 Android 上編寫高性能代碼的一種語(yǔ)言(使用C99標(biāo)準(zhǔn),運(yùn)行時(shí)機(jī)器再次優(yōu)化編譯, 可以均衡的運(yùn)行在多個(gè)CPU 和 GPU上,有一個(gè)半徑限制小于25的限制),效率最高

簡(jiǎn)單聊聊 FastBlur

因?yàn)樾Ч膶?shí)現(xiàn)是基于 Java 的,所以有必要先來(lái)了解一下方法如何使用。

public static Bitmap doBlur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap)

可以看出,使用方法非常簡(jiǎn)單,傳入待虛化的bitmap、虛化程度(一般為8)、是否重用flag,最后返回模糊后的bitmap。

但如果直接把一張大圖傳入進(jìn)行虛化,很容易就會(huì)產(chǎn)生OOM內(nèi)存溢出,那就意味著我只能虛化小圖,這樣才能防止內(nèi)存溢出。但是我并不想換其他圖,那么,我們就應(yīng)該把這張圖縮小。

平時(shí)我們對(duì)圖片縮小,必然會(huì)帶來(lái)很明顯的清晰度的損失,但高斯模糊本身的目的就是要實(shí)現(xiàn)模糊的效果,因此實(shí)際上的效果差別不大,幾乎可以忽略。

同時(shí)由于圖片縮小后再進(jìn)行模糊處理,需要處理的像素點(diǎn)和半徑都變小,從而使得模糊處理速度加快。

ReScale
public static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter) {}

我們可以利用Bitmap的 createScaledBitmap() 方法來(lái)進(jìn)行bitmap的縮放。其中前三個(gè)參數(shù)很明顯,其中寬高我們可以選擇為原圖尺寸的1/5;第四個(gè)filter是指縮放的效果,filter為true則會(huì)得到一個(gè)邊緣平滑的bitmap,反之,則會(huì)得到邊緣鋸齒、pixelrelated的bitmap。這里我們要對(duì)縮放的圖片進(jìn)行虛化,所以無(wú)所謂邊緣效果,filter=false。

所以,我們要使用

int scaleRatio = 5;// 縮放比例 此處代表1/5
int blurRadius = 8;// 虛化程度
Bitmap scaledBitmap = Bitmap.createScaledBitmap(originBitmap,
    originBitmap.getWidth() / scaleRatio,
    originBitmap.getHeight() / scaleRatio,
    false);
Bitmap blurBitmap = FastBlur.doBlur(scaledBitmap, blurRadius, true);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageBitmap(blurBitmap);

可以得到如下效果:

從圖中可以看出,首先可以確定思路是對(duì)的;然后,可以看出毛玻璃效果還不是特別的明顯。為了得到如iOS那樣的虛化效果,我們有兩種方法:

增大scaleRatio縮放比,使用更小的bitmap去虛化可以得到更好的模糊效果,而且有利于占用內(nèi)存的減??;

增大blurRadius,可以得到更高程度的虛化,不過(guò)會(huì)導(dǎo)致CPU更加intensive

這里筆者通過(guò)增大縮放比來(lái)實(shí)驗(yàn)。

scaleRatio = 10

scaleRatio = 20

通過(guò)上面對(duì)比圖我們可以找出最適合自己的虛化效果。

再來(lái)聊聊 RenderScript

RenderScript 主要 在Android中的對(duì)圖形進(jìn)行處理,RenderScript 采用C99語(yǔ)法進(jìn)行編寫,主要優(yōu)勢(shì)在于性能較高。在 API 11 的時(shí)候被加入到 Android 中。同時(shí),Google提供了android.support.v8.renderscript兼容包,能夠?qū)崿F(xiàn)更低版本的兼容。

RenderScript 提供了一個(gè)用于實(shí)現(xiàn)高斯模糊的封裝類 ScriptIntrinsicBlur ,因?yàn)樵?API 17 后才正式適配到 Android ,所以在不使用兼容包的情況下只能兼容到4.2的設(shè)備。但是,我們有兼容包啊向下兼容不是夢(mèng)。

準(zhǔn)備階段 引入兼容包

方法很簡(jiǎn)單,只需在build.gradle中加入:

defaultConfig {
        ....
        // 就是這么簡(jiǎn)單
        renderscriptTargetApi 19
        renderscriptSupportModeEnabled true
    }

另外由于一些廠商會(huì)深度定制Android系統(tǒng),所以一些必要的依賴文件會(huì)被他們直接去掉,這導(dǎo)致一些型號(hào)的設(shè)備上調(diào)用RenderScriptd的部分方法時(shí)會(huì)報(bào)錯(cuò)。遇到這種兼容問(wèn)題的話,需要加上這些可能丟失的文件。
其實(shí)也簡(jiǎn)單,打開(kāi)android_sdk/build-tools/選擇19以上版本/renderscript/lib/packaged我們可以看見(jiàn)3個(gè)包含.so文件的文件夾。

直接復(fù)制這三個(gè)文件加到項(xiàng)目工程的 jniLibs 包下,沒(méi)有的話去建一個(gè)。

如果首次創(chuàng)建 jniLibs 文件夾,還需要在 build.gradle 的 android{} 中加入:

sourceSets {
        main {
            jniLibs.srcDirs = ["jniLibs"]
        }
    }

針對(duì)使用的混淆的同學(xué),需要在混淆中加入:

-keep class android.support.v8.renderscript.** { *; }
實(shí)現(xiàn)高斯模糊

將核心實(shí)現(xiàn)方法 ScriptIntrinsicBlur 封裝成工具類。

import android.support.v8.renderscript.*;  // 需要導(dǎo)入v8包,否則無(wú)法向下兼容

public class BlurBitmapUtil {

    /***
     * 圖片縮放比例 (例如 1/10)
     */
    private static int scaleRatio = 10;

    /**
     * 對(duì)圖片進(jìn)行高斯模糊
     *
     * @param context    上下文對(duì)象
     * @param image      需要模糊的圖片
     * @param blurRadius 模糊半徑,由于性能限制,這個(gè)值的取值區(qū)間為(0至25f)
     * @return 模糊處理后的圖片
     */
    public static Bitmap blurBitmap(Context context, Bitmap image, @FloatRange(from = 1, to = 25)
            float blurRadius) {
        // 計(jì)算圖片縮小后的長(zhǎng)寬
        int width = Math.round(image.getWidth() / scaleRatio);
        int height = Math.round(image.getHeight() / scaleRatio);

        // 創(chuàng)建一張縮小后的圖片做為渲染的圖片
        Bitmap bitmap = Bitmap.createScaledBitmap(image, width, height, false);

        // 創(chuàng)建RenderScript內(nèi)核對(duì)象
        RenderScript rs = RenderScript.create(context);
        // 創(chuàng)建一個(gè)模糊效果的RenderScript的工具對(duì)象,第二個(gè)參數(shù)Element相當(dāng)于一種像素處理的算法,高斯模糊的話用這個(gè)就好
        ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));

        // 由于RenderScript并沒(méi)有使用VM來(lái)分配內(nèi)存,所以需要使用Allocation類來(lái)創(chuàng)建和分配內(nèi)存空間
        // 創(chuàng)建Allocation對(duì)象的時(shí)候其實(shí)內(nèi)存是空的,需要使用copyTo()將數(shù)據(jù)填充進(jìn)去
        Allocation input = Allocation.createFromBitmap(rs, bitmap);
        // 創(chuàng)建相同類型的Allocation對(duì)象用來(lái)輸出
        Type type = input.getType();
        Allocation output = Allocation.createTyped(rs, type);

        // 設(shè)置渲染的模糊程度, 25f是最大模糊度
        blurScript.setRadius(blurRadius);
        // 設(shè)置blurScript對(duì)象的輸入內(nèi)存
        blurScript.setInput(input);
        // 將輸出數(shù)據(jù)保存到輸出內(nèi)存中
        blurScript.forEach(output);
        // 將數(shù)據(jù)填充到bitmap中
        output.copyTo(bitmap);

        // 銷毀它們釋放內(nèi)存
        input.destroy();
        output.destroy();
        blurScript.destroy();
        rs.destroy();
        type.destroy();

        return bitmap;
    }

使用 RenderScript 增加虛化程度的方法和 FastBlur 一樣,有兩種方法:

增大scaleRatio縮放比,使用更小的bitmap去虛化可以得到更好的模糊效果,而且有利于占用內(nèi)存的減?。?/p>

增大blurRadius,可以得到更高程度的虛化,不過(guò)會(huì)導(dǎo)致虛化時(shí)間變長(zhǎng)

但因?yàn)?RenderScript 的天然優(yōu)勢(shì)(低級(jí)語(yǔ)言, 運(yùn)行時(shí)機(jī)器再次優(yōu)化編譯, 可以均衡的運(yùn)行在多個(gè)CPU 和 GPU上),所以這里筆者通過(guò)增大虛化程度來(lái)實(shí)驗(yàn),縮放比例為 1/10,實(shí)際運(yùn)用時(shí)可以根據(jù)需求在對(duì)虛化程度和縮放比例上采取一個(gè)合適的數(shù)值。

blurRadius = 5

blurRadius = 15

blurRadius = 25

通過(guò)上面對(duì)比圖我們可以找出最適合自己的虛化效果。

目前來(lái)看,為何 Google 設(shè)置這個(gè)25的限制, 原因應(yīng)該有兩個(gè) :

半徑大于25的話耗時(shí)就成為了一個(gè)瓶頸;

如果想實(shí)現(xiàn)大于25的模糊效果,可以通過(guò)縮小原圖,模糊,再放大來(lái)達(dá)到同樣的效果

總結(jié)

以上就是如何用 FastBlur 和 RenderScript 在 Android 上實(shí)現(xiàn)和 iOS 一樣的高斯模糊效果的簡(jiǎn)單介紹,雖然在性能上毋庸置疑是 RenderScript 上最好,但是在一些使用場(chǎng)景上 FastBlur 耗時(shí)會(huì)更短,所以我們各取所需,根據(jù)實(shí)際需求去選擇使用。

另一種可能性

上面說(shuō)的2種解決方案都是從性能和效率出發(fā)的產(chǎn)物,但如果我的需求就是從網(wǎng)絡(luò)上加載一張圖片(比如頭像),然后再高斯模糊化當(dāng)背景,走一遍轉(zhuǎn)換成bitma再將其轉(zhuǎn)換成高斯模糊的流程或許會(huì)有一點(diǎn)點(diǎn)麻煩,這里我再提供一種簡(jiǎn)單快捷的解決方案 —— 基于Glid加載框架去實(shí)現(xiàn)一鍵 加載網(wǎng)絡(luò)圖片→高斯模糊化→展示。

引入兼容包

首先在build.gradle中加入圖片框架需要的庫(kù)和圖片工具庫(kù):

defaultConfig {
        ....
        compile "com.yutianran.maven:super-adapter:1.0.0"
        compile "jp.wasabeef:glide-transformations:2.0.2"
}
然后就開(kāi)寫,一行代碼即可
Glide.with(this).load(url).bitmapTransform(new BlurTransformation(this,25)).into(imageView);

需要的參數(shù)很分別是

上下文對(duì)象

圖片url

上下文對(duì)象,虛化數(shù)值

imageView控件

效果如上,可以看出 glide-transformations 庫(kù)的虛化效果也是十分不錯(cuò)的,但對(duì)圖片本身做的縮放應(yīng)該不是很多,所以在加載速度上會(huì)弱于 FastBlur 和 RenderScript ,但作為輕量級(jí)圖片而言足夠了。

Code

相關(guān)代碼已上傳至Github:BlurView,歡迎Star,F(xiàn)ork。

參考文獻(xiàn)

[[譯] RenderScript:簡(jiǎn)單而快速的圖像處理](https://toutiao.io/posts/44zw...

圖片高斯模糊效果簡(jiǎn)單優(yōu)化

高斯模糊效果實(shí)現(xiàn)方案及性能對(duì)比

Android:簡(jiǎn)單靠譜的動(dòng)態(tài)高斯模糊效果

教你一分鐘實(shí)現(xiàn)動(dòng)態(tài)模糊效果

什么?IOS的專利?Android也能流暢實(shí)現(xiàn)毛玻璃效果(高斯模糊)效果

Android 高斯模糊總結(jié)

Android RenderScript 簡(jiǎn)單高效實(shí)現(xiàn)圖片的高斯模糊效果

干貨 一種快速毛玻璃虛化效果實(shí)現(xiàn)--Android

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/66982.html

相關(guān)文章

  • Android簡(jiǎn)單、高性能的高斯模糊(毛玻璃)效果(附源碼)

    摘要:毛玻璃效果相信很多朋友都眼紅很久了,隔壁系統(tǒng)對(duì)高斯模糊早就大范圍使用了,咱們卻絲毫不為所動(dòng),于是就只能靠廣大開(kāi)發(fā)者咯。 毛玻璃效果相信很多朋友都眼紅很久了,隔壁ios系統(tǒng)對(duì)高斯模糊早就大范圍使用了,咱們Android卻絲毫不為所動(dòng),于是就只能靠廣大開(kāi)發(fā)者咯。 這是目前市面上性能最高的方案,也不知道最初是哪位大神寫的,我也只是拿來(lái)封裝一下,變得更簡(jiǎn)單、更好用,加上了陰影遮罩的效果。 先來(lái)...

    walterrwu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<