今天在看干货的时候看到一个android高斯模糊图,what!?根本没听过。表示想要了解一下,最后看到我郭大神写的一篇博客,顿悟。然后就尝试写了一下。
先上一个效果图。
然后就解释一下这个高斯模糊图是怎么回事:对指定像素和其周围像素进行加权平均来得到最终结果,使用高斯分布作为滤波器。
说白了甚至可以用它来做美图,去个痘拉,加个马赛克都是有可能的。
Android平台上进行模糊渲染是一个相当耗CPU也相当耗时的操作,一旦处理不好,卡顿是在所难免的。在Android推出RenderScript之后,测试表明,使用RenderScript的渲染效率和使用C/C++不相上下,但是使用RenderScript却比使用JNI简单地多!同时,Android团队提供了RenderScript
的支持库,使得在低版本的Android平台上也能使用。
还是贴上主要代码:
/**
* Created by L on 2017/10/12.
*/
public class BlurBitmapUtil {
/**
* 图片缩放比例
*/
private static final float BITMAP_SCALE = 0.4f;
/**
* 最大模糊度(在0.0到25.0之间)
*/
private static final float BLUR_RADIUS = 25f;
/**
* 模糊图片的具体方法
*
* @param context 上下文对象
* @param image 需要模糊的图片
* @return 模糊处理后的图片
*/
public static Bitmap blur(Context context, Bitmap image) {
// 计算图片缩小后的长宽
int width = Math.round(image.getWidth() * BITMAP_SCALE);
int height = Math.round(image.getHeight() * BITMAP_SCALE);
// 将缩小后的图片做为预渲染的图片。
Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false);
// 创建一张渲染后的输出图片。
Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
// 创建RenderScript内核对象
RenderScript rs = RenderScript.create(context);
// 创建一个模糊效果的RenderScript的工具对象
ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
// 由于RenderScript并没有使用VM来分配内存,所以需要使用Allocation类来创建和分配内存空间。
// 创建Allocation对象的时候其实内存是空的,需要使用copyTo()将数据填充进去。
Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
// 设置渲染的模糊程度, 25f是最大模糊度
blurScript.setRadius(BLUR_RADIUS);
// 设置blurScript对象的输入内存
blurScript.setInput(tmpIn);
// 将输出数据保存到输出内存中
blurScript.forEach(tmpOut);
// 将数据填充到Allocation中
tmpOut.copyTo(outputBitmap);
return outputBitmap;
}
}
当然仅有这个也完成不了的接着就是activity
/**
* 2017-10-12 Mr.Li Android 高斯模糊图
*/
public class MainActivity extends AppCompatActivity {
//原图img1,模糊img2,控件
private ImageView img1,img2;
//进度条
private SeekBar sb;
//显示进度文字控件
private TextView text;
//透明度
private int mAlpha;
//原始图片 oldbitmap;模糊后的图片 newbitmap
private Bitmap oldbitmap,newbitmap;
private MainActivity context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
//绑定组件,初始化视图
initView();
//获取图片
oldbitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.pzy);
newbitmap = BlurBitmapUtil.blur(this,oldbitmap);
// 填充模糊后的图像和原图
img2.setImageBitmap(newbitmap);
img1.setImageBitmap(oldbitmap);
// 处理seekbar滑动事件
setSeekBar();
}
private void setSeekBar() {
sb.setMax(100);
sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
mAlpha = i;
img1.setAlpha((int) (255 - mAlpha * 2.55));
text.setText(String.valueOf(mAlpha));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
private void initView() {
img1 = (ImageView)findViewById(R.id.img1);
img2 = (ImageView)findViewById(R.id.img2);
sb = (SeekBar)findViewById(R.id.sb);
text = (TextView)findViewById(R.id.text);
}
}
紧接着就是xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="diagram.blur.gaussian.gaussianblurdiagram.MainActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<!--android:scaleType="centerCrop"
当图片大于ImageView的宽高:以图片的中心
点和ImageView的中心点为基准,按比例缩小图片-->
<ImageView
android:id="@+id/img2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@mipmap/pzy"
android:scaleType="centerCrop" />
<ImageView
android:id="@+id/img1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<SeekBar
android:id="@+id/sb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="5dp" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="0"
android:textSize="24sp" />
</LinearLayout>
</LinearLayout>
这样一个简单的高斯模糊图就出现了。
要谢谢我查看过的那些前辈写的博客让我客观的正确的认识了其中的原理。
这个小dome已经上传至github,有兴趣的小伙伴也可以下载下来看一下的。
附:点击打开链接