高斯模糊

最近在翻看学长之前的佳作,发现了个好玩的,也是自己以前一直想实现却没有实现的一个东西,高斯模糊。话不多说,发车!

[TOC]

一、高斯模糊是什么

在 Android 中,Dialog 的高斯模糊指的是将 Dialog 界面进行模糊处理,使得 Dialog 呈现出一种模糊、朦胧的效果。

高斯模糊是一种常见的图像处理技术,通过对图像中的像素进行加权平均来减少图像的细节和噪点,从而达到模糊效果。在 Dialog 中使用高斯模糊可以用来实现一些特殊的视觉效果,或者提供一种更加柔和的界面体验。

在 Android 中,实现 Dialog 的高斯模糊通常有两种方式:

使用系统提供的 DialogFragment:可以在 DialogFragment 中使用 Window.setBackgroundDrawable() 方法来设置 Dialog 的背景,通过自定义 Drawable 实现高斯模糊效果,然后将该 Drawable 设置为 Dialog 的背景即可。

自定义 Dialog 样式:可以通过自定义 Dialog 的样式文件,在样式文件中设置 Dialog 的背景为自定义的 Drawable,然后在该 Drawable 中实现高斯模糊效果。

本文将采用第二种方式进行实现,第一种本人也实现过,不过是学习他人代码进行实现的。

二、实现Dialog高斯模糊的准备工作

首先做一些准备工作,在项目中导入这些东西。

这是自定义的一个dialog主题样式。

1
2
3
4
5
6
7
<style name="SquareEntranceDialogStyle" parent="@android:style/Theme.Dialog">
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">false</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>

这是一张白色的背景图。

1
2
3
4
5
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="15dp"/>
<solid android:color="@color/white" />
</shape>

dialog弹窗的话,这里由于是自定义,因人而异,我就不贴学长的代码了,因为是学习学长的哈哈。

三、具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//获取截图 这里是获取当前截图的一个函数,下面也会贴出代码。
Bitmap bitmap = getCurrentBitmap();
//自定义的dialog
AddCategoryDialog dialog = new AddCategoryDialog.Builder(mainActivity).setCancelableOutside(true).create();
Window window = dialog.getWindow();
View decorView = window.getDecorView();
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
//两个 flag 要结合使用,表示让应用的主体内容占用系统状态栏的空间
int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(option);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
//设置导航栏颜
window.setNavigationBarColor(Color.TRANSPARENT);
//内容扩展到导航栏
window.setType(WindowManager.LayoutParams.TYPE_APPLICATION_PANEL);
//最重要的地方,高斯模糊对bitmap进行处理
Bitmap blurBg = BlurBitmap.blur(mainActivity, bitmap);
window.setBackgroundDrawable(new BitmapDrawable(getResources(), blurBg));
bitmap.recycle();

View view_bt = LayoutInflater.from(mainActivity).inflate(R.layout.dialog_add_category,null);

红色的这里是你的dialog布局
ImageView bt_cancel = (ImageView) view_bt.findViewById(R.id.bt_cancel_add);
bt_cancel.setOnClickListener(view_cancel -> {
//取消dialog
dialog.dismiss();
});
ImageView bt_finish = (ImageView) view_bt.findViewById(R.id.bt_finish_add);
//字数监控
EditText text = (EditText) view_bt.findViewById(R.id.edit_add);
TextView count_text = (TextView) view_bt.findViewById(R.id.count_name);
dialog.setContentView(view_bt);
//回收资源
dialog.setOnDismissListener(dialog1 -> {
// 对话框取消时释放背景图bitmap
if (blurBg != null && !blurBg.isRecycled()) {
blurBg.recycle();
Handler handler = new Handler();
new Thread(){
@Override
public void run() {
super.run();
handler.post(new Runnable() {
@Override
public void run() {
System.out.println("我是在new Hhread里面使用handler.post");
}
});
}
}.start();
}
});
dialog.show();
1
2
3
4
5
6
7
8
public Bitmap getCurrentBitmap () {
View activityView = getWindow().getDecorView();
activityView.setDrawingCacheEnabled(true);
activityView.destroyDrawingCache();
activityView.buildDrawingCache();
Bitmap bmp = activityView.getDrawingCache();
return bmp;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class BlurBitmap {
/**
* 图片缩放比例
*/
private static final float BITMAP_SCALE = 0.4f;
/**
* 最大模糊度(在0.0到25.0之间)
*/
private static final float BLUR_RADIUS = 12f;

/**
* 模糊图片的具体方法
*
* @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内核对象 Android的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);
// 将输出数据保存到输出内存中 这是将上一步高斯模糊拿到的数据放到tepOut里面
blurScript.forEach(tmpOut);

// 将数据填充到Allocation中 使用tmpOut.copyTo()方法将模糊处理后的结果复制到输出到outputBitmap;
tmpOut.copyTo(outputBitmap);

return outputBitmap;
}
}

当然,上面也说了还可以用另外一种方式实现,可以自己去尝试。

高斯模糊
https://crwei996.github.io/2023/09/23/高斯模糊/
Author
Crwei996
Posted on
September 23, 2023
Licensed under