Android動(dòng)態(tài)模糊效果的快速實(shí)現(xiàn)方法
寫(xiě)在前面
現(xiàn)在,越來(lái)越多的App里面使用了模糊效果,這種模糊效果稱(chēng)之為高斯模糊。大家都知道,在Android平臺(tái)上進(jìn)行模糊渲染是一個(gè)相當(dāng)耗CPU也相當(dāng)耗時(shí)的操作,一旦處理不好,卡頓是在所難免的。一般來(lái)說(shuō),考慮到效率,渲染一張圖片最好的方法是使用OpenGL,其次是使用C++/C,使用Java代碼是效率是最低,速度也是最慢的。但是Android推出RenderScript之后,我們就有了選擇,測(cè)試表明,使用RederScript的渲染效率和使用C++/C不相上下,但是使用RenderScript卻比使用JNI簡(jiǎn)單得多!同時(shí),Android團(tuán)隊(duì)提供了RenderScript的支持庫(kù),使得在低版本的Android平臺(tái)上也能使用。
不過(guò)在使用RenderScript之前,對(duì)于模糊一張圖片,需要注意的是,我們應(yīng)該盡量不要使用原尺寸分辨率的圖片,最好將圖片縮小比例,這小渲染的效率要高一些,速度也更快一些。
什么是RenderScript
RenderScript是一種低級(jí)的高性能編程語(yǔ)言,用于3D渲染和處理密集型計(jì)算(3D播放等和關(guān)于CPU密集型的計(jì)算)。一直以來(lái)Android 在繪圖性能的表現(xiàn)一直差強(qiáng)人意,引入NDK之后才有所改善,而在Honeycomb 中發(fā)布了RenderScript 這一殺手級(jí)在Framework 后,大大的增加了Android本地語(yǔ)言的執(zhí)行能力和計(jì)算能力。現(xiàn)在網(wǎng)上介紹RenderScript的文章非常少,附上一篇博客,大家可以能更好理解這門(mén)語(yǔ)言。
關(guān)于Android RenderScript 的詳細(xì)說(shuō)明和一些實(shí)用文檔
如果需要詳細(xì)了解,可以查看官方文檔RenderScript
動(dòng)態(tài)模糊的實(shí)現(xiàn)
使用之前,先要在Module build.gradle里面作下面的定義:
MainActivity.java
package com.jackie.blurimage; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.ImageView; import android.widget.SeekBar; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private ImageView mBlurImage, mOriginImage; private SeekBar mSeekBar; private TextView mSeekProgress; private int mAlpha; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); initEvent(); } private void initView() { mBlurImage = (ImageView) findViewById(R.id.blur_image); mOriginImage = (ImageView) findViewById(R.id.origin_image); mSeekBar = (SeekBar) findViewById(R.id.seek_bar); mSeekProgress = (TextView) findViewById(R.id.seek_progress); } private void initData() { // 獲取圖片 Bitmap originBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.blur); Bitmap blurBitmap = BlurUtils.blur(this, originBitmap); // 填充模糊后的圖像和原圖 mBlurImage.setImageBitmap(blurBitmap); mOriginImage.setImageBitmap(originBitmap); } private void initEvent() { mSeekBar.setMax(100); mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { mAlpha = progress; mOriginImage.setAlpha((int) (255 - mAlpha * 2.55)); mSeekProgress.setText(String.valueOf(mAlpha)); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); } }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <FrameLayout android:layout_width="match_parent" android:layout_weight="1" android:layout_height="0dp"> <ImageView android:id="@+id/blur_image" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/blur"/> <ImageView android:id="@+id/origin_image" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop"/> </FrameLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="80dp" android:orientation="vertical"> <SeekBar android:id="@+id/seek_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" android:layout_marginTop="@dimen/activity_vertical_margin"/> <TextView android:id="@+id/seek_progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="0" android:textSize="24sp"/> </LinearLayout> </LinearLayout>
從上面的代碼可以看出,在FrameLayout上放了兩張圖片,然后動(dòng)態(tài)更改圖片的透明度來(lái)達(dá)到動(dòng)態(tài)模糊效果。
BlurUtils.java
package com.jackie.blurimage; import android.content.Context; import android.graphics.Bitmap; import android.renderscript.Allocation; import android.renderscript.Element; import android.renderscript.RenderScript; import android.renderscript.ScriptIntrinsicBlur; /** * Created by Jackie on 2017/1/21. * 高斯模糊工具類(lèi) */ public class BlurUtils { /** * 圖片縮放比例 */ private static final float SCALE_DEGREE = 0.4f; /** * 最大模糊度(在0.0到25.0之間) */ private static final float BLUR_RADIUS = 25f; /** * 模糊圖片 * @param context 上下文 * @param bitmap 需要模糊的圖片 * @return 模糊處理后的圖片 */ public static Bitmap blur(Context context,Bitmap bitmap) { //計(jì)算圖片縮小的長(zhǎng)寬 int width = Math.round(bitmap.getWidth() * SCALE_DEGREE); int height = Math.round(bitmap.getHeight() * SCALE_DEGREE); //將縮小后的圖片作為預(yù)渲染的圖片 Bitmap inputBitmap = Bitmap.createScaledBitmap(bitmap, width, height, false); //創(chuàng)建一張渲染后的輸入圖片 Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap); //創(chuàng)建RenderScript內(nèi)核對(duì)象 RenderScript renderScript = RenderScript.create(context); //創(chuàng)建一個(gè)模糊效果的RenderScript的工具對(duì)象 ScriptIntrinsicBlur scriptIntrinsicBlur = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript)); /** * 由于RenderScript并沒(méi)有使用VM來(lái)分配內(nèi)存,所以需要使用Allocation類(lèi)來(lái)創(chuàng)建和分配內(nèi)存空間。 * 創(chuàng)建Allocation對(duì)象的時(shí)候其實(shí)內(nèi)存是空的,需要使用copyTo()將數(shù)據(jù)填充進(jìn)去。 */ Allocation inputAllocation = Allocation.createFromBitmap(renderScript, inputBitmap); Allocation outputAllocation = Allocation.createFromBitmap(renderScript, outputBitmap); //設(shè)置渲染的模糊程度,25f是最大模糊度 scriptIntrinsicBlur.setRadius(BLUR_RADIUS); //設(shè)置ScriptIntrinsicBlur對(duì)象的輸入內(nèi)存 scriptIntrinsicBlur.setInput(inputAllocation); //將ScriptIntrinsicBlur輸出數(shù)據(jù)保存到輸出內(nèi)存中 scriptIntrinsicBlur.forEach(outputAllocation); //將數(shù)據(jù)填充到Allocation中 outputAllocation.copyTo(outputBitmap); return outputBitmap; } }
效果圖如下,妹紙一枚!
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android 動(dòng)態(tài)高斯模糊效果教程
- 教你快速實(shí)現(xiàn)Android動(dòng)態(tài)模糊效果
- Android實(shí)現(xiàn)動(dòng)態(tài)高斯模糊效果
- Android圖片特效:黑白特效、圓角效果、高斯模糊
- Android中實(shí)現(xiàn)布局背景模糊化處理的方法
- Android模糊處理實(shí)現(xiàn)圖片毛玻璃效果
- Android模糊處理簡(jiǎn)單實(shí)現(xiàn)毛玻璃效果
- Android關(guān)于Glide的使用(高斯模糊、加載監(jiān)聽(tīng)、圓角圖片)
- Android調(diào)用系統(tǒng)拍照裁剪圖片模糊的解決方法
- Android 實(shí)現(xiàn)圖片模糊、高斯模糊、毛玻璃效果的三種方法
相關(guān)文章
從零開(kāi)始學(xué)android實(shí)現(xiàn)計(jì)算器功能示例分享(計(jì)算器源碼)
這篇文章主要介紹了android實(shí)現(xiàn)的計(jì)算器功能示例,可以加減乘除;可以倒退,可以清空文本,大家參考使用吧2014-02-02Android引用開(kāi)源框架通過(guò)AsyncHttpClient實(shí)現(xiàn)文件上傳
這篇文章主要介紹了Android引用開(kāi)源框架通過(guò)AsyncHttpClient實(shí)現(xiàn)文件上傳,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01Gradle配置教程之自定義APK名稱(chēng)與輸出路徑
Gradle是一個(gè)基于JVM的富有突破性構(gòu)建工具,下面這篇文章主要給大家介紹了關(guān)于Gradle配置教程之自定義APK名稱(chēng)與輸出路徑的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-03-03Android使用ContentProvider實(shí)現(xiàn)跨進(jìn)程通訊示例詳解
這篇文章主要為大家介紹了Android使用ContentProvider實(shí)現(xiàn)跨進(jìn)程通訊示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03解決VSCode調(diào)試react-native android項(xiàng)目錯(cuò)誤問(wèn)題
這篇文章主要介紹了VSCode調(diào)試react-native android項(xiàng)目錯(cuò)誤解決辦法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12Android手勢(shì)ImageView三部曲 第二部
這篇文章主要為大家詳細(xì)介紹了Android手勢(shì)ImageView三部曲的第二部,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03Android?Flutter繪制有趣的?loading加載動(dòng)畫(huà)
在網(wǎng)絡(luò)速度較慢的場(chǎng)景,一個(gè)有趣的加載會(huì)提高用戶(hù)的耐心和對(duì)?App?的好感。本篇我們利用Flutter?的?PathMetric來(lái)玩幾個(gè)有趣的?loading?效果,感興趣的可以動(dòng)手嘗試一下2022-07-07