Android动态模糊效果的快速实现方法
作者:shineflowers 发布时间:2022-06-20 13:14:26
写在前面
现在,越来越多的App里面使用了模糊效果,这种模糊效果称之为高斯模糊。大家都知道,在Android平台上进行模糊渲染是一个相当耗CPU也相当耗时的操作,一旦处理不好,卡顿是在所难免的。一般来说,考虑到效率,渲染一张图片最好的方法是使用OpenGL,其次是使用C++/C,使用Java代码是效率是最低,速度也是最慢的。但是Android推出RenderScript之后,我们就有了选择,测试表明,使用RederScript的渲染效率和使用C++/C不相上下,但是使用RenderScript却比使用JNI简单得多!同时,Android团队提供了RenderScript的支持库,使得在低版本的Android平台上也能使用。
不过在使用RenderScript之前,对于模糊一张图片,需要注意的是,我们应该尽量不要使用原尺寸分辨率的图片,最好将图片缩小比例,这小渲染的效率要高一些,速度也更快一些。
什么是RenderScript
RenderScript是一种低级的高性能编程语言,用于3D渲染和处理密集型计算(3D播放等和关于CPU密集型的计算)。一直以来Android 在绘图性能的表现一直差强人意,引入NDK之后才有所改善,而在Honeycomb 中发布了RenderScript 这一杀手级在Framework 后,大大的增加了Android本地语言的执行能力和计算能力。现在网上介绍RenderScript的文章非常少,附上一篇博客,大家可以能更好理解这门语言。
关于Android RenderScript 的详细说明和一些实用文档
如果需要详细了解,可以查看官方文档RenderScript
动态模糊的实现
使用之前,先要在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上放了两张图片,然后动态更改图片的透明度来达到动态模糊效果。
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.
* 高斯模糊工具类
*/
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) {
//计算图片缩小的长宽
int width = Math.round(bitmap.getWidth() * SCALE_DEGREE);
int height = Math.round(bitmap.getHeight() * SCALE_DEGREE);
//将缩小后的图片作为预渲染的图片
Bitmap inputBitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);
//创建一张渲染后的输入图片
Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
//创建RenderScript内核对象
RenderScript renderScript = RenderScript.create(context);
//创建一个模糊效果的RenderScript的工具对象
ScriptIntrinsicBlur scriptIntrinsicBlur = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript));
/**
* 由于RenderScript并没有使用VM来分配内存,所以需要使用Allocation类来创建和分配内存空间。
* 创建Allocation对象的时候其实内存是空的,需要使用copyTo()将数据填充进去。
*/
Allocation inputAllocation = Allocation.createFromBitmap(renderScript, inputBitmap);
Allocation outputAllocation = Allocation.createFromBitmap(renderScript, outputBitmap);
//设置渲染的模糊程度,25f是最大模糊度
scriptIntrinsicBlur.setRadius(BLUR_RADIUS);
//设置ScriptIntrinsicBlur对象的输入内存
scriptIntrinsicBlur.setInput(inputAllocation);
//将ScriptIntrinsicBlur输出数据保存到输出内存中
scriptIntrinsicBlur.forEach(outputAllocation);
//将数据填充到Allocation中
outputAllocation.copyTo(outputBitmap);
return outputBitmap;
}
}
效果图如下,妹纸一枚!


猜你喜欢
- java线程同步原理java会为每个object对象分配一个monitor,当某个对象的同步方法(synchronizedmethods)被
- 会话技术会话:一次会话中包含多次请求和响应。一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止功能:在一次会话的范围内
- 1. 定义在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。2. 使用的
- Java内存分配与管理是Java的核心技术之一,之前我们曾介绍过Java的内存管理与内存泄露以及Java垃圾回收方面的知识,今天我们再次深入
- 前言古语有云:道为术之灵,术为道之体;以道统术,以术得道。其中:“道”指“规律、道理、理论”,“术”指“方法、技巧、技术”。意思是:“道”是
- 本文实例为大家分享了Android SQLite数据库连接实现登录功能的具体代码,供大家参考,具体内容如下布局文件border.xml<
- springboot多模块化整合mybatis,mapper自动注入失败问题启动类添加@MapperScan或@ComponentScan,
- 简介:Springboot使用Mybatis&Mybatis-plus 两者文件映射配置略有不同,之前我用的是Mybatis,但公司
- tomcat内存溢出设置JAVA_OPTS答案1设置Tomcat启动的初始内存其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xm
- 废话不多说了,直接给大家贴java代码了。具体代码如下所示:/*支付流程*//****Controller.java 代码如下:*/@Req
- * 缓存内存缓存本地缓存(SD卡缓存)网络缓存缓存顺序:首先从网络获取图片资源,然后将当前的图片缓存到本地,然后再缓存到内存中,那么下次访问
- 使用Spring3 实现用户登录以及权限认证这里我就简单介绍一下,我在实现的时候处理的一些主要的实现。1.用户登录 <form act
- 本文实例讲述了Android编程设置屏幕亮度的方法。分享给大家供大家参考,具体如下:使用场景最近在研究AndroidL Settings的代
- 一、简介上篇介绍了一个自己做的管理系统,最近空闲的时间自己在继续做,把之前登录时候自定义的 * 过滤器换成了基于SpringSecurity
- 本文实例讲述了Android实现打开各种文件的intent方法。分享给大家供大家参考,具体如下:import android.app.Act
- 本文实例讲述了Android简单获取经纬度的方法。分享给大家供大家参考,具体如下:public void getLoc() {
- 本文实现的功能有:1、 初始化游戏窗口2、初始化游戏的界面3、初始化游戏的说明面板4、随机生成下落方块5、方块下落速度变化6、判断方块是否可
- 一 模式介绍重试模式,是应用在异常处理中,发生异常的时候,能够对业务程序进行重新调用,在实际中,可以使用Polly提供稳定,简单的用法,自己
- Druid是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0、DBCP、PROXOOL等DB池的优点,同时加入了日志监控,可以很好的
- 一. 什么是Spring SecuritySpring Security是Spring家族的一个安全管理框架, 相比于另一个安全框架Shir