Android使用RenderScript实现图片的高斯模糊效果

首先来看一下什么是高斯模糊效果呢?

高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop、GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪声以及降低细节层次。这种模糊技术生成的图像,其视觉效果就像是经过一个半透明屏幕在观察图像,这与镜头焦外成像效果散景以及普通照明阴影中的效果都明显不同。高斯平滑也用于计算机视觉算法中的预先处理阶段,以增强图像在不同比例大小下的图像效果(参见尺度空间表示以及尺度空间实现)。 从数学的角度来看,图像的高斯模糊过程就是图像与正态分布做卷积。由于正态分布又叫作高斯分布,所以这项技术就叫作高斯模糊。图像与圆形方框模糊做卷积将会生成更加精确的焦外成像效果。由于高斯函数的傅立叶变换是另外一个高斯函数,所以高斯模糊对于图像来说就是一个低通滤波器。

看完了对高斯模糊术语的介绍。下面来看一下如何使用Android来实现高斯模糊效果。

通过在网上资料查找,有以下4种方法可以实现:

  • RenderScript
  • Java算法
  • NDK算法
  • openGL

处理一整张图片这么大计算量的工作,openGL 的性能最好,而用 java 实现肯定是最差的了。而 RenderScrip t和 NDK 的性能相当。但是对我来说,NDK 和 openGL 我无可奈何,最终考虑,使用RenderScript 应该是最适合的。

但并不是说 RenderScript 就是完全没有问题的:

  • 模糊半径(radius)越大,性能要求越高,模糊半径不能超过25,所以并不能得到模糊度非常高的图片。
  • ScriptIntrinsicBlur 在API 17时才被引入,如果需要在 Android 4.2 以下的设备上实现,就需要引入 RenderScript Support Library ,当然,安装包体积会相应的增大。

那么什么是RenderScript呢?

Google在API 11中引入了RenderScrip,一个强大的图片处理框架,帮助Android开发人员专注于图片处理算法而不是API的调度工作。使用RenderScript进行图片处理,还需要了解RenderScript Intrinsics,一些可以帮助RenderScript快速实现各种图片处理的操作类。比如ScriptIntrinsicBlur,可以简单高效地帮助我们实现高斯模糊效果。

那知道了什么是RenderScript,接下来我们就开始使用这个东东。

RenderScript 实现

首先在 app 目录下 build.gradle 文件中添加如下代码:

defaultConfig {......testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"// RenderScriptIntrinsics 提供了一些可以帮助我们快速实现各种图片处理的操作类,// 例如,ScriptIntrinsicBlur,可以简单高效实现 高斯模糊效果。renderscriptTargetApi 19renderscriptSupportModeEnabled true}

引入之后,开始编写RenderScriptBitmapBlur.java文件

import android.content.Context;
import android.graphics.Bitmap;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.v8.renderscript.Allocation;
import android.support.v8.renderscript.Element;
import android.support.v8.renderscript.RenderScript;
import android.support.v8.renderscript.ScriptIntrinsicBlur;/*** 作者    yunyang* 时间    2018/11/12 14:39* 文件    Demo* 描述   处理图片类——高斯模糊*/
public class RenderScriptBitmapBlur {private RenderScript renderScript;public RenderScriptBitmapBlur(@NonNull Context context) {// 实例化一个新的渲染脚本this.renderScript = RenderScript.create(context);}public Bitmap getBlurBitmap(@IntRange(from = 1, to = 25) int radius, Bitmap original) {// 使用Renderscript和in/out位图创建分配(in/out)Allocation input = Allocation.createFromBitmap(renderScript, original);Allocation output = Allocation.createTyped(renderScript, input.getType());// 使用Renderscript创建一个固有的模糊脚本ScriptIntrinsicBlur scriptIntrinsicBlur = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript));// 设置模糊半径:0 < radius <= 25scriptIntrinsicBlur.setRadius(radius);// 执行渲染脚本scriptIntrinsicBlur.setInput(input);scriptIntrinsicBlur.forEach(output);// 将out分配创建的最终位图复制到originaloutput.copyTo(original);return original;}}

注意:ScriptIntrinsicBlur的相关方法只支持API 17及以上版本的系统,为了兼容旧版本,Google供了support.v8包,在使用RenderScript和Intrinsics类时,引入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;

然后就可以直接使用 RenderScriptBitmapBlur,滑动SeekBar 的值,实现不同程度的模糊了。

import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;import com.maigu.yang.gaussianblur.helper.RenderScriptBitmapBlur;public class MainActivity extends AppCompatActivity {private RenderScriptBitmapBlur mRenderScriptGaussianBlur;private ImageView container;private ImageView imageView;private SeekBar seekBar;private TextView text_Progress;private Button btn_start_dialog;private LinearLayout layout;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();container.setVisibility(View.GONE);layout.setVisibility(View.VISIBLE);seekBar.setMax(25);seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {text_Progress.setText(String.valueOf(progress));}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {int radius = seekBar.getProgress();if (radius < 1) {radius = 1;}Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.meizitu);imageView.setImageBitmap(mRenderScriptGaussianBlur.getBlurBitmap(radius, bitmap));}});btn_start_dialog.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {container.setVisibility(View.VISIBLE);layout.setDrawingCacheEnabled(true);layout.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_LOW);Bitmap bitmap = layout.getDrawingCache();container.setImageBitmap(mRenderScriptGaussianBlur.getBlurBitmap(25, bitmap));layout.setVisibility(View.INVISIBLE);AlertDialog dialog = new AlertDialog.Builder(MainActivity.this).create();dialog.setMessage("弹出Dialog(启用高斯模糊)也可以自行弹出悬浮层");dialog.setButton(DialogInterface.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();}});dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {container.setVisibility(View.GONE);layout.setVisibility(View.VISIBLE);}});dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {@Overridepublic void onCancel(DialogInterface dialog) {container.setVisibility(View.GONE);layout.setVisibility(View.VISIBLE);}});dialog.show();}});}private void initView() {container = (ImageView) findViewById(R.id.container);imageView = (ImageView) findViewById(R.id.imageView);seekBar = (SeekBar) findViewById(R.id.seekBar);text_Progress = (TextView) findViewById(R.id.text_Progress);btn_start_dialog = (Button) findViewById(R.id.btn_start_dialog);layout = (LinearLayout) findViewById(R.id.layout);mRenderScriptGaussianBlur = new RenderScriptBitmapBlur(this);}}

然后是MainActivity.java文件中使用的布局文件activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/activity_main"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><ImageViewandroid:id="@+id/container"android:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="centerCrop" /><LinearLayoutandroid:id="@+id/layout"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><ImageViewandroid:id="@+id/imageView"android:layout_width="match_parent"android:layout_height="180dp"android:scaleType="centerCrop"android:src="@drawable/meizitu" /><SeekBarandroid:id="@+id/seekBar"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="16dp" /><TextViewandroid:id="@+id/text_Progress"android:layout_width="match_parent"android:layout_height="wrap_content"android:textAlignment="center" /><Buttonandroid:id="@+id/btn_start_dialog"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_marginTop="16dp"android:text="弹出Dialog(启用高斯模糊)"android:textAllCaps="false"tools:ignore="HardcodedText" /></LinearLayout></FrameLayout>

meizitu.jpg

通过滑动SeekBar 的值,对图片实现不同程度的模糊,或者点击弹出Dialog,实现对图片的模糊效果。

效果图如下所示:

关于Android平台的图片模糊处理,在GitHub上有一些较为优秀的开源类库,如:

  • Blurry
  • 500px-android-blur
  • 等等等。。。

我一般常用的是Blurry,(链式调用,行云流水,很舒服)Blurry是一个简单的模糊库Android。

添加Module依赖

dependencies {implementation 'jp.wasabeef:blurry:2.1.1'
}

关于它的简单使用,

模糊图片/View

             // 模糊图片/ViewBlurry.with(BlurryActivity.this).radius(25).sampling(1).color(Color.argb(66, 0, 255, 255)).async().capture(findViewById(R.id.right_top)).into((ImageView) findViewById(R.id.right_top));

模糊ViewGroup

             // 模糊ViewGroupBlurry.with(BlurryActivity.this).radius(25).sampling(2).async().animate(500).onto((ViewGroup) findViewById(R.id.content));

Blur Options 模糊选项

Radius 半径
Down Sampling 下采样
Color Filter 彩色滤光片
Asynchronous Support 异步支持
Animation (Overlay Only) 动画(仅覆盖)

直接上代码,简单使用Blurry。

BlurryActivity.文件

import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;import jp.wasabeef.blurry.Blurry;public class BlurryActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_blurry);findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {long startMs = System.currentTimeMillis();// 模糊图片/ViewBlurry.with(BlurryActivity.this).radius(25).sampling(1).color(Color.argb(66, 0, 255, 255)).async().capture(findViewById(R.id.right_top)).into((ImageView) findViewById(R.id.right_top));Blurry.with(BlurryActivity.this).radius(10).sampling(8).async().capture(findViewById(R.id.right_bottom)).into((ImageView) findViewById(R.id.right_bottom));Blurry.with(BlurryActivity.this).radius(25).sampling(1).color(Color.argb(66, 255, 255, 0)).async().capture(findViewById(R.id.left_bottom)).into((ImageView) findViewById(R.id.left_bottom));Log.d(getString(R.string.app_name),"TIME " + String.valueOf(System.currentTimeMillis() - startMs) + "ms");}});findViewById(R.id.button).setOnLongClickListener(new View.OnLongClickListener() {private boolean blurred = false;@Overridepublic boolean onLongClick(View v) {if (blurred) {Blurry.delete((ViewGroup) findViewById(R.id.content));} else {long startMs = System.currentTimeMillis();// 模糊ViewGroupBlurry.with(BlurryActivity.this).radius(25).sampling(2).async().animate(500).onto((ViewGroup) findViewById(R.id.content));Log.d(getString(R.string.app_name),"TIME " + String.valueOf(System.currentTimeMillis() - startMs) + "ms");}blurred = !blurred;return true;}});}
}

BlurryActivity.文件的布局文件activity_blurry.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/content"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><Viewandroid:id="@+id/spacer"android:layout_width="0dp"android:layout_height="0dp"android:layout_centerInParent="true" /><ImageViewandroid:id="@+id/right_top"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_above="@id/spacer"android:layout_alignLeft="@id/spacer"android:contentDescription="@null"android:scaleType="centerCrop"android:src="@drawable/meizitutwo" /><ImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:layout_above="@id/spacer"android:layout_alignRight="@id/spacer"android:contentDescription="@null"android:scaleType="centerCrop"android:src="@drawable/meizitutwo" /><ImageViewandroid:id="@+id/right_bottom"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_below="@id/spacer"android:layout_alignLeft="@id/spacer"android:contentDescription="@null"android:scaleType="centerCrop"android:src="@drawable/meizitutwo" /><ImageViewandroid:id="@+id/left_bottom"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_below="@id/spacer"android:layout_alignRight="@id/spacer"android:contentDescription="@null"android:scaleType="centerCrop"android:src="@drawable/meizitutwo" /><ImageViewandroid:id="@+id/overlay"android:layout_width="match_parent"android:layout_height="match_parent"android:contentDescription="@null" /><Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:background="@null"android:elevation="10dp"android:text="@string/app_name"android:textColor="@color/colorAccent"android:textSize="88sp"android:textStyle="bold" /></RelativeLayout>

meizitutwo.jpg

点击BLURRY,实现四张妹子图不同的渲染模糊效果。

长按BLURRY实现屏幕内容区域模糊,在长按取消BLURRY屏幕内容区域模糊效果。

运行效果图预览:

源代码下载

Android使用RenderScript实现图片的高斯模糊效果相关推荐

  1. CSS3:图片的高斯模糊效果

    CSS3:图片的高斯模糊效果 demo演示地址 最近项目中需要预览视频中加马赛克的效果(高斯模糊),于是找到了css3的一个属性filter来进行高斯模糊 filter(滤镜) 可以用来定义图片或者d ...

  2. 给图片增加高斯模糊效果

    前一阵研究了图片的滤镜效果,今天单独把高斯模糊的拿出来,供小伙伴们一起学习. 高斯模糊的效果其实灰常简单,苹果这边已经给了一些现成的封装CIFilter,下面一起来看一看代码吧~ // // View ...

  3. 【游戏开发实战】Unity ShaderGraph实现图片的高斯模糊效果

    文章目录 一.前言 二.最终效果 三.高斯模糊的原理 四.ShaderGraph的高斯模糊实现 一.前言 之前我写了一篇文章:ShaderGraph使用教程与各种特效案例:Unity2020 有网友私 ...

  4. CSS背景图片高斯模糊效果

    问题来源 背景图片的高斯模糊效果已经屡见不鲜了,最典型的也就是QQ音乐的播放器页面,看起来有种回忆过去的感觉.CSS如何实现这种效果呢?其实也很简单,利用CSSfilter属性就能实现,下面是在uni ...

  5. Android中为网络图片设置高斯模糊效果

    参考了这篇文章:               Android:简单靠谱的动态高斯模糊效果 写一个方法,用来对Bitmap进行高斯模糊: public static Bitmap blurBitmap( ...

  6. android+动态模糊效果,Android 动态高斯模糊效果教程

    写在前面 最近一直在做毕设项目的准备工作,考虑到可能要用到一个模糊的效果,所以就学习了一些高斯模糊效果的实现.比较有名的就是 FastBlur 以及它衍生的一些优化方案,还有就是今天要说的Render ...

  7. 图片高斯模糊效果的实现

    本片文章实现了个人中心用户头像的高斯模糊效果. 首先是效果图: 点击按钮,用户头像的背景图片变成模糊背景,这样看起来更清爽一些,如果有小伙伴需要这样的效果,赶紧跟着看下去吧! 一.主界面MainAct ...

  8. js实现图片虚化_js canvas画布实现高斯模糊效果

    最近项目中有一个需求是实现图片的局部模糊效果,看上去一个挺难的效果.在实现局部模糊效果前,首先能够实现全部模糊.经过和度娘的一番较劲后,找到了一个不错的案例,然后在他的基础上,经过一番修改,和备注,实 ...

  9. js实现图片虚化_StackBlur.js - 实现Canvas高斯模糊效果

    越来越多的app在背景图中使用高斯模糊效果,如yahoo天气,感觉效果做得很炫.现在使用StackBlur.js在网页上也可以对Canvas实现高斯模糊效果,运行相当流畅,画面一点不卡. 引入资源 在 ...

最新文章

  1. 你需要知道的加密算法
  2. Configure NFS Server On AIX 6.1
  3. rabbitMQ 实战 高效部署分布式消息队列 读书笔记
  4. 在 Snoop 中使用 PowerShell 脚本进行更高级的 UI 调试
  5. 偏振模色散及保偏光纤的正确理解
  6. JS学习笔记(二)变量、作用域及内存问题
  7. GameJS——Game Library written in JavaScript
  8. Ubuntu搜狗输入法, 输入中文时只显示拼音,不显示中文选择框
  9. 施耐德PLC Unity Pro xl 软件使用一
  10. 简单网络管理协议SNMP通讯基础篇-熊健-专题视频课程
  11. 《一切都是最好的安排》脑图
  12. 指针指向的地址的说明
  13. 用函数发生器输出高阻态程序
  14. 描写火车站场景_求几段描写火车站的段落,而且是描写的极好的段落
  15. entity 与dto 区别
  16. jsp实现一个简单的投票系统
  17. 关于使用JavaPOI 导出Excel多级联动的一些方法
  18. 看别人分享的图片停不下来,还有这么有意思的网站?
  19. 仿京东、淘宝首页,通过两层嵌套的RecyclerView实现tab的吸顶效果
  20. Google Earth Engine(GEE)——计算水体面积提取2013-2020年青海湖面积的为例

热门文章

  1. 最快速的文件传输软件,解析镭速文件传输软件
  2. 通过OpenWrt路由器实现王者荣耀、快手、抖音过滤
  3. Android事件总线 EventBus3.0用法学习
  4. 关于Android Framework渲染机制,你需要学习哪些?
  5. css表格文字位置调整,word表格中的文字距离表格四周太远,怎么才能调的近一些,除了调字大小。...
  6. Android系统SD卡各类文件夹名称
  7. 种植牙术后的注意事项
  8. 路由器绑定mac地址
  9. 真无线蓝牙耳机哪款适合女孩子?高颜值佩戴舒适,这五款蓝牙耳机可以考虑
  10. 外存及虚拟存储器管理