Android中实现模糊效果通常有两种方式:高斯模糊和Stack Blur模糊。
一、高斯模糊
高斯模糊是一种比较常见的模糊效果,它能够使得图像变得柔和,边缘模糊化,处理后的图像更加良好的满足用户视觉需求。在Android中实现高斯模糊通常有两种方式:使用RenderScript实现和使用Bitmap实现。
1. 使用RenderScript实现
RenderScript是Google在Android 3.0之后推出的一种高性能的计算库,它是为处理复杂计算任务而设计的。使用RenderScript可以很轻松地实现高斯模糊效果。
首先需要在gradle中添加RenderScript库的依赖:
```
android {
...
defaultConfig {
...
renderscriptTargetApi 23
renderscriptSupportModeEnabled true
}
}
```
然后在代码中实现高斯模糊方法:
```
public static Bitmap blurBitmap(Context context, Bitmap bitmap, float radius) {
// 将bitmap转换成可变的bitmap
Bitmap mutableBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
// 创建一个RenderScript对象
RenderScript rs = RenderScript.create(context);
// 创建高斯模糊的脚本
ScriptIntrinsicBlur gaussianBlurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
// 创建输出图片
Allocation allocationOut = Allocation.createFromBitmap(rs, mutableBitmap);
// 将输入图片加入高斯模糊脚本当中
gaussianBlurScript.setInput(Allocation.createFromBitmap(rs, mutableBitmap));
// 设置模糊半径
gaussianBlurScript.setRadius(radius);
// 开始高斯模糊处理
gaussianBlurScript.forEach(allocationOut);
// 将输出图片结果保存在可变的bitmap中
allocationOut.copyTo(mutableBitmap);
// 释放内存
allocationOut.destroy();
gaussianBlurScript.destroy();
rs.destroy();
return mutableBitmap;
}
```
2. 使用Bitmap实现
使用Bitmap实现高斯模糊效果,需要利用Android提供的API可以获取到Bitmap图片的像素点,并对这些像素点进行变换从而达到模糊效果。下面是具体实现方式:
```
public static Bitmap blurBitmap(Bitmap bitmap, float radius) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
// 利用Canvas绘制一个与原图片大小相同的Bitmap,并将该Bitmap传递给RenderScript用来保存结果
Canvas canvas = new Canvas(output);
Paint paint = new Paint();
// 开启图像抗锯齿
paint.setAntiAlias(true);
// 设置画笔颜色为空
paint.setColor(Color.TRANSPARENT);
// 设置画笔Xfermode模式为SRC_IN(只显示叠加的部分,其他部分彻底透明)
PorterDuffXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
paint.setXfermode(xfermode);
canvas.drawBitmap(bitmap, 0, 0, paint);
// 利用Stack Blur算法进行高斯模糊处理
output = StackBlur.blurNatively(output, radius, true);
return output;
}
```
二、Stack Blur模糊
Stack Blur模糊是另一种比较常见的模糊效果,它是一种非常快速和有效的算法来模糊图像。Stack Blur模糊在移动端应用中非常流行,因为它既快速又有效。下面是Stack Blur模糊算法的实现方法。
```
public static Bitmap blur(Bitmap image, float radius) {
int width = Math.round(image.getWidth());
int height = Math.round(image.getHeight());
Bitmap inputBitmap = Bitmap.createScaledBitmap(image,width,height,false);
Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
// 保证模糊半径为正数
if (radius <= 0) {
return inputBitmap;
}
int iRadius = (int)(radius + 0.5f);
int[] input = new int[width * height];
inputBitmap.getPixels(input, 0, width, 0, 0, width, height);
int[] output = new int[width * height];
int[] sums = new int[Math.max(width, height) * 2];
int r1 = iRadius + 1;
int divSum = (r1 + 1) * (r1 + 1);
int[] divs = new int[256 * divSum];
for (int i = 0; i < 256 * divSum; i++) {
divs[i] = i / divSum;
}
int w4 = width - 1;
int h4 = height - 1;
int rsum;
int gsum;
int bsum;
int x;
int y;
int p1;
int p2;
int yi;
int yw;
int y1 = 0;
int y2;
int[] bMul = new int[] { 1, 221, 16, 235, 64, 36, 17, 253, 134, 15, 151, 60, 197, 192, 48, 211 };
int[] gMul = new int[] { 15, 34, 185, 38, 32, 6, 191, 60, 226, 1, 61, 243, 50, 12, 211, 156 };
int[] rMul = new int[] { 186, 44, 230, 22, 34, 130, 183, 253, 56, 80, 225, 48, 217, 23, 235, 109 };
for (y = 0; y < height; y++) {
yw = y * width;
rsum = 0;
gsum = 0;
bsum = 0;
for (int i = -iRadius; i <= iRadius; i++) {
p1 = input[yw + (Math.min(w4, Math.max(i, 0)))];
rsum += (p1 & 0xff0000) >> 16;
gsum += (p1 & 0x00ff00) >> 8;
bsum += (p1 & 0x0000ff);
}
for (x = 0; x < width; x++) {
output[yw + x] = (divs[rsum] << 16) + (divs[gsum] << 8) + divs[bsum];
if (y == 0) {
sums[x] = Math.min(x + iRadius + 1, w4);
p1 = input[yw + sums[x]];
p2 = input[yw + Math.max(x - iRadius, 0)];
rsum += ((p1 & 0xff0000) - (p2 & 0xff0000)) >> 16;
gsum += ((p1 & 0x00ff00) - (p2 & 0x00ff00)) >> 8;
bsum += (p1 & 0x0000ff) - (p2 & 0x0000ff);
} else {
sums[x] = Math.min(x + iRadius + 1, w4) + y * width;
p1 = input[yw + sums[x]];
p2 = input[yw + Math.max(x - iRadius, 0) + y * width];
rsum += ((p1 & 0xff0000) - (p2 & 0xff0000)) >> 16;
gsum += ((p1 & 0x00ff00) - (p2 & 0x00ff00)) >> 8;
bsum += (p1 & 0x0000ff) - (p2 & 0x0000ff);
}
}
}
for (x = 0; x < width; x++) {
rsum = 0;
gsum = 0;
bsum = 0;
int yp = -iRadius * width;
for (int i = -iRadius; i <= iRadius; i++) {
yi = Math.max(0, yp) + x;
rsum += (output[yi] & 0xff0000) >> 16;
gsum += (output[yi] & 0x00ff00) >> 8;
bsum += (output[yi] & 0x0000ff);
yp += width;
}
yi = x;
y1 = 0;
for (y = 0; y < height; y++) {
// 将处理后的像素点赋给output数组
output[yi] = (divs[rsum] << 16) + (divs[gsum] << 8) + divs[bsum];
// 如果y2没有超过上限,则对数组elements以及rsum、gsum、bsum做一些处理
if (x == 0) {
sums[y] = Math.min(y + iRadius + 1, h4) * width;
p1 = output[y * width + sums[y]];
p2 = input[y * width + Math.max(0, y - iRadius) * width];
rsum += (p1 & 0xff0000) - (p2 & 0xff0000);
gsum += (p1 & 0x00ff00) - (p2 & 0x00ff00);
bsum += (p1 & 0x0000ff) - (p2 & 0x0000ff);
} else {
p1 = output[y * width + sums[y1]];
p2 = output[y * width + Math.max(0, y1 - iRadius) * width];
rsum += (p1 & 0xff0000) - (p2 & 0xff0000);
gsum += (p1 & 0x00ff00) - (p2 & 0x00ff00);
bsum += (p1 & 0x0000ff) - (p2 & 0x0000ff);
}
yi += width;
y1++;
}
}
// 将处理后的结果存到你paddingBitmap中去
Bitmap paddingBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
paddingBitmap.setPixels(output, 0, width, 0, 0, width, height);
return paddingBitmap;
}
```
总之,实现android模糊效果,需要我们掌握两种常用的算法:高斯模糊和Stack Blur模糊,只有了解了两种算法,我们才能够根据实际需要进行选择,提高我们的开发效率和代码的实现质量。