Implementation method of android dialog background blurring effect
- 2021-09-05 01:02:43
- OfStack
Recent projects have such requirements: when starting an dialog in activity, the background of the started dialog is set to the blurred picture of the started acitivity.
Implementation ideas:
1. Screen capture to get the current activity interface
2. Blur the captured photos
3. Set the blurred picture as the background of dialog
1. Screen capture to get the interface of the current activity
private Bitmap takeScreenShot(Activity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap b1 = view.getDrawingCache();
// Get screen length and height
int width = activity.getResources().getDisplayMetrics().widthPixels;
int height = activity.getResources().getDisplayMetrics().heightPixels;
Bitmap bmp = Bitmap.createBitmap(b1, 0, 0, width, height);
view.destroyDrawingCache();
return bmp;
}
Note here: The default dialog is full screen, activity is also full screen without status bar. If there is a status bar to obtain the status bar size, subtract the status bar size when creating the picture.
2. Get the picture to blur, here the fuzzy algorithm, is found from the Internet, specifically Gaussian blur. Specific code in the following tool class.
3. Set the blurred picture to the background of dialog
//blurBackgroundDrawer Is a blurred background picture
Window window = getWindow();
window.setBackgroundDrawable(new BitmapDrawable(mContext.getResources(), blurBackgroundDrawer));
Note: Blurring the picture may be slow, and it takes 3-4 seconds at the beginning of measurement. The solution is to reduce the acquired screen, then blur it, and then enlarge the picture after blurring.
The following is the tool class code that encapsulates the background fuzzification effect. How to use it: Just test it into the project and call it where the fuzzification effect is needed:
Bitmap bmp = getBlurBackgroundDrawer (activity); That's enough.
public class FastBlurUtility {
/**
* Get a blurred background picture
* @param activity Get the blurred background activity
* @return Blurred background picture
*/
public static Bitmap getBlurBackgroundDrawer(Activity activity) {
Bitmap bmp = takeScreenShot(activity);
return startBlurBackground(bmp);
}
/**
* Screen capture
* @param activity Screenshot activity
* @return Screen shot
*/
private static Bitmap takeScreenShot(Activity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap b1 = view.getDrawingCache();
// Get screen length and height
int width = activity.getResources().getDisplayMetrics().widthPixels;
int height = activity.getResources().getDisplayMetrics().heightPixels;
Bitmap bmp = Bitmap.createBitmap(b1, 0, 0, width, height);
view.destroyDrawingCache();
return bmp;
}
private static Bitmap startBlurBackground(Bitmap bkg) {
long startMs = System.currentTimeMillis();
float radius = 20; // Degree of fuzziness
Bitmap overlay = fastblur(small(bkg), (int) radius);
Log.i("FastBlurUtility", "=====blur time:" + (System.currentTimeMillis() - startMs));
return big(overlay);
}
/**
* Enlarge a picture
* @param bitmap Picture to be enlarged
* @return An enlarged picture
*/
private static Bitmap big(Bitmap bitmap) {
Matrix matrix = new Matrix();
matrix.postScale(4f, 4f);
Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
return resizeBmp;
}
/**
* Zoom out a picture
* @param bitmap Pictures that need to be reduced
* @return A scaled-down picture
*/
private static Bitmap small(Bitmap bitmap) {
Matrix matrix = new Matrix();
matrix.postScale(0.25f, 0.25f);
Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
return resizeBmp;
}
/**
* Blur a picture
* @param sentBitmap Need blurred picture
* @param radius Degree of fuzziness
* @return Blurred picture
*/
private static Bitmap fastblur(Bitmap sentBitmap, int radius) {
Bitmap 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++) {
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);
}
}