高斯模糊
原文地址:https://github.com/zuiwuyuan/FastBlur_VoiceChat
private int scaleRatio =5;
private int blurRadius =5;
private void initView() {
img = findViewById(R.id.img);
Bitmap img_bg = BitmapFactory.decodeResource(getResources(),R.mipmap.touxiang);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(img_bg,
img_bg.getWidth() /scaleRatio,
img_bg.getHeight() /scaleRatio,
false);
img_bg = GaoSiMoHu.doBlur(scaledBitmap,blurRadius,true);
img.setImageBitmap(img_bg);
}
引用的类
public class GaoSiMoHu {
public static Bitmap doBlur(Bitmap sentBitmap,int radius,boolean canReuseInBitmap) {
Bitmap bitmap;
if (canReuseInBitmap) {
bitmap = sentBitmap;
}else {
bitmap = sentBitmap.copy(sentBitmap.getConfig(),true);
}
if (radius <1) {
return (null);
}
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int[] pix =new int[w * h];
bitmap.getPixels(pix,0, w,0,0, w, h);
int wm = w -1;
int hm = h -1;
int wh = w * h;
int div = radius + radius +1;
int r[] =new int[wh];
int g[] =new int[wh];
int b[] =new int[wh];
int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
int vmin[] =new int[Math.max(w, h)];
int divsum = (div +1) >>1;
divsum *= divsum;
int dv[] =new int[256 * divsum];
for (i =0; i <256 * divsum; i++) {
dv[i] = (i / divsum);
}
yw = yi =0;
int[][] stack =new int[div][3];
int stackpointer;
int stackstart;
int[] sir;
int rbs;
int r1 = radius +1;
int routsum, goutsum, boutsum;
int rinsum, ginsum, binsum;
for (y =0; y < h; y++) {
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum =0;
for (i = -radius; i <= radius; i++) {
p = pix[yi + Math.min(wm, Math.max(i,0))];
sir = stack[i + radius];
sir[0] = (p &0xff0000) >>16;
sir[1] = (p &0x00ff00) >>8;
sir[2] = (p &0x0000ff);
rbs = r1 - Math.abs(i);
rsum += sir[0] * rbs;
gsum += sir[1] * rbs;
bsum += sir[2] * rbs;
if (i >0) {
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
}else {
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
}
}
stackpointer = radius;
for (x =0; x < w; x++) {
r[yi] = dv[rsum];
g[yi] = dv[gsum];
b[yi] = dv[bsum];
rsum -= routsum;
gsum -= goutsum;
bsum -= boutsum;
stackstart = stackpointer - radius + div;
sir = stack[stackstart % div];
routsum -= sir[0];
goutsum -= sir[1];
boutsum -= sir[2];
if (y ==0) {
vmin[x] = Math.min(x + radius +1, wm);
}
p = pix[yw + vmin[x]];
sir[0] = (p &0xff0000) >>16;
sir[1] = (p &0x00ff00) >>8;
sir[2] = (p &0x0000ff);
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
rsum += rinsum;
gsum += ginsum;
bsum += binsum;
stackpointer = (stackpointer +1) % div;
sir = stack[(stackpointer) % div];
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
rinsum -= sir[0];
ginsum -= sir[1];
binsum -= sir[2];
yi++;
}
yw += w;
}
for (x =0; x < w; x++) {
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum =0;
yp = -radius * w;
for (i = -radius; i <= radius; i++) {
yi = Math.max(0, yp) + x;
sir = stack[i + radius];
sir[0] = r[yi];
sir[1] = g[yi];
sir[2] = b[yi];
rbs = r1 - Math.abs(i);
rsum += r[yi] * rbs;
gsum += g[yi] * rbs;
bsum += b[yi] * rbs;
if (i >0) {
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
}else {
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
}
if (i < hm) {
yp += w;
}
}
yi = x;
stackpointer = radius;
for (y =0; y < h; y++) {
// Preserve alpha channel: ( 0xff000000 & pix[yi] )
pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] <<16) | (dv[gsum] <<8) | dv[bsum];
rsum -= routsum;
gsum -= goutsum;
bsum -= boutsum;
stackstart = stackpointer - radius + div;
sir = stack[stackstart % div];
routsum -= sir[0];
goutsum -= sir[1];
boutsum -= sir[2];
if (x ==0) {
vmin[y] = Math.min(y + r1, hm) * w;
}
p = x + vmin[y];
sir[0] = r[p];
sir[1] = g[p];
sir[2] = b[p];
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
rsum += rinsum;
gsum += ginsum;
bsum += binsum;
stackpointer = (stackpointer +1) % div;
sir = stack[stackpointer];
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
rinsum -= sir[0];
ginsum -= sir[1];
binsum -= sir[2];
yi += w;
}
}
bitmap.setPixels(pix,0, w,0,0, w, h);
return (bitmap);
}
}