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);
 }
}

Related articles: