我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何在Android中使用RenderScript实现一个毛玻璃模糊效果

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何在Android中使用RenderScript实现一个毛玻璃模糊效果

今天就跟大家聊聊有关如何在Android中使用RenderScript实现一个毛玻璃模糊效果,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

RenderScript 介绍

在开始之前,先看下 RenderScript 的官方介绍:

RenderScript is a framework for running computationally intensive tasks at high performance on Android. RenderScript is primarily oriented for use with data-parallel computation, although serial workloads can benefit as well. The RenderScript runtime parallelizes work across processors available on a device, such as multi-core CPUs and GPUs. This allows you to focus on expressing algorithms rather than scheduling work. RenderScript is especially useful for applications performing image processing, computational photography, or computer vision.

大致意思就是说 RenderScript 是 Android 平台上为了计算密集型任务的一中高性能框架,并且RenderScript 尤其对图像的处理特别有用。另外,RenderScript 之所以效率高是因为其底层是 C 实现的。

使用 RenderScript Support Library

为了可以兼容到更早的版本,我们直接使用 android.support.v8.renderscript(支持API level 9+)包下的,而不使用android.renderscript(支持API level 11+)

以 Android Studio 为例,打开你的 app 的 build.gradle 文件,在 android 的 defaultConfig 结点添加两句:

renderscriptTargetApi 18renderscriptSupportModeEnabled true

其中 renderscriptTargetApi 的值官方说的是从 11 到最新的 API Level 都可以

这样我们等下导包就可以导 v8 内的了。

模糊背景

局部模糊

先上一张我们要实现的效果图:

如何在Android中使用RenderScript实现一个毛玻璃模糊效果

这里可以看到实现的是局部模糊,在图片的正中间有一个 TextView,TextView 的背景部分做了模糊处理。

先大致说下模糊的主要步骤(完全模糊步骤一样):

  1. 首先取出 TextView 在 ImageView 正上方处的那一块背景

  2. 然后对取出的那一块背景做模糊处理

  3. 最后把模糊处理后的背景再设为 TextView 的背景

这样,就可以达到我们图片中的局部模糊效果,具体的过程在代码中有详细的注释。

下面先贴上布局文件:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="20dp"> <FrameLayout  android:layout_width="300dp"  android:layout_height="300dp"  android:layout_centerInParent="true">  <ImageView   android:id="@+id/image"   android:layout_width="match_parent"   android:layout_height="match_parent"   android:scaleType="centerCrop"   android:class="lazy" data-src="@drawable/img"/>  <TextView   android:id="@+id/text"   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:layout_gravity="center"   android:text="Melody"   android:textColor="@android:color/white"   android:textSize="45sp"/> </FrameLayout></RelativeLayout>

再贴上java代码:

public class MainActivity extends Activity implements Runnable { private static final String TAG = "MainActivity"; private ImageView mImage; private TextView mText; @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  mImage = (ImageView) findViewById(R.id.image);  mText = (TextView) findViewById(R.id.text);  // onCreate()内无法到ImageView的背景,所以需要 post 到消息队列内稍后执行  mImage.post(this); } @Override public void run() {  blur(getImageViewBitmap(mImage), mText); }  public Bitmap getImageViewBitmap(ImageView imageView) {  imageView.setDrawingCacheEnabled(true);  // 取出ImageView的Bitmap  Bitmap bitmap = imageView.getDrawingCache();  // 拷贝一份bitmap用作模糊  Bitmap bitmapCopy = bitmap.copy(bitmap.getConfig(), true);  imageView.setDrawingCacheEnabled(false);  return bitmapCopy; }  public void blur(Bitmap inputBitmap, View targetView) {  // 创建一个和目标View(需要背景被模糊的View)宽高一样的空的 outputBitmap  Bitmap outputBitmap = Bitmap.createBitmap((int) (targetView.getMeasuredWidth()),    (int) (targetView.getMeasuredHeight()), Bitmap.Config.ARGB_8888);  // 将 outputBitmap 关联在 canvas 上  Canvas canvas = new Canvas(outputBitmap);  // 画布移动到目标 View 在父布局中的位置  canvas.translate(-targetView.getLeft(), -targetView.getTop());  Paint paint = new Paint();  paint.setFlags(Paint.FILTER_BITMAP_FLAG);  // 将要模糊的 inputBitmap 绘制到 outputBitmap 上  // 因为刚才做了 translate 操作,这样就可以裁剪到目标 View 在父布局内的那一块背景到 outputBitmap 上  canvas.drawBitmap(inputBitmap, 0, 0, paint);  // ----接下来做模糊 outputBitmap 处理操作----  // 创建 RenderScript  RenderScript rs = RenderScript.create(this);  Allocation input = Allocation.createFromBitmap(rs, outputBitmap);  Allocation output = Allocation.createTyped(rs, input.getType());  // 使用 ScriptIntrinsicBlur 类来模糊图片  ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(    rs, Element.U8_4(rs));  // 设置模糊半径 ( 取值范围为( 0.0f , 25f ] ,半径越大,模糊效果也越大)  blur.setRadius(25f);  blur.setInput(input);  // 模糊计算  blur.forEach(output);  // 模糊 outputBitmap  output.copyTo(outputBitmap);  // 将模糊后的 outputBitmap 设为目标 View 的背景  targetView.setBackground(new BitmapDrawable(getResources(), outputBitmap));  rs.destroy(); }}

导的是 v8 的包:

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

完全模糊

上面是局部模糊,然后我们改变一下 TextView 的宽高铺满父布局,使其和 ImageView 大小一样来实现完全模糊效果:

...<TextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="Melody" android:textColor="@android:color/white" android:textSize="45sp"/>...

java代码部分不需要改变,下面再看效果图:

效率如何?

为了查看操作耗时,我使用 Log 在 blur() 方法的开头和结束地方分别计算了时间,然后查看时间差:

10-09 17:04:23.664 23665-23665/com.melodyxxx.blurdemo2 E/MainActivity: spend: 120ms

可以看到居然花了 120ms,显然效率不够高,有没有优化的方法?(测试机型为 魅族 PRO 6)

效率优化

上面的是直接将原 ImageView 的 bitmap 直接模糊处理,效率不够高,所以我们可以先将原图片进行压缩处理,然后在进行模糊,下面为关键代码,scaleFactor 为压缩比例大小,例如 scaleFactor 为 2,代表先将原图压缩为原来的 1/2,然后进行模糊,效率会高很多。

...Bitmap outputBitmap = Bitmap.createBitmap((int) (mTargetView.getMeasuredWidth() / scaleFactor),  (int) (mTargetView.getMeasuredHeight() / scaleFactor), Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(outputBitmap);canvas.translate(-mTargetView.getLeft() / scaleFactor, -mTargetView.getTop() / scaleFactor);canvas.scale(1 / scaleFactor, 1 / scaleFactor);Paint paint = new Paint();paint.setFlags(Paint.FILTER_BITMAP_FLAG);canvas.drawBitmap(mInputBitmap, 0, 0, paint);...

下面是 Demo 效果图:

如何在Android中使用RenderScript实现一个毛玻璃模糊效果

结果:

压缩比例为 2 时:耗时 19 ms

压缩比例为 8 时:耗时 2 ms

根据压缩比例配合不同的模糊半径可以达到不同模糊效果。

再来看 Demo 效果图中拖动 SeekBar 可以动态的实现模糊效果,首先想到的方法是每次拖动时实时计算模糊,这样的效率肯定不行,还会造成卡顿,我这里的方法是先将图片最大化模糊一次设给上方 ImageView 的背景即可,然后 SeekBar 拖动时,只需要改变最上方或者下方图片的透明度就可以达到上面的效果。

看完上述内容,你们对如何在Android中使用RenderScript实现一个毛玻璃模糊效果有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注编程网行业资讯频道,感谢大家的支持。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

如何在Android中使用RenderScript实现一个毛玻璃模糊效果

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何在Android中使用RenderScript实现一个毛玻璃模糊效果

今天就跟大家聊聊有关如何在Android中使用RenderScript实现一个毛玻璃模糊效果,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。RenderScript 介绍在开始之前,先
2023-05-31

Android开发中怎么实现一个iOS中的毛玻璃效果

本篇文章为大家展示了Android开发中怎么实现一个iOS中的毛玻璃效果,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。实现代码: 2023-05-31

在Android开发中利用RenderScript实现一个动态高斯模糊效果

在Android开发中利用RenderScript实现一个动态高斯模糊效果?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。什么是RenderScriptRenderScript是
2023-05-31

如何在Android应用中实现一个Gallery画廊效果

这期内容当中小编将会给大家带来有关如何在Android应用中实现一个Gallery画廊效果,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。画廊 使用Gallery表示,按水平方向显示内容,并且可以用手指直接
2023-05-31

如何在Android中利用ConstraintLayout实现一个动画效果

这篇文章将为大家详细讲解有关如何在Android中利用ConstraintLayout实现一个动画效果,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。xml布局: