android dialog背景模糊化效果实现方法

作者:lbcab 时间:2023-09-17 02:31:23 

最近做项目有这样的需求: 在activity中启动一个dialog时, 启动的dialog的背景设为启动acitivity的模糊化图片.

实现思路:

1. 截屏, 获取当前activity的界面
2. 将获取的照片进行模糊化
3. 将模糊化的图片设为dialog的背景

1.截屏, 获取当前activity的界面


private Bitmap takeScreenShot(Activity activity) {
 View view = activity.getWindow().getDecorView();
 view.setDrawingCacheEnabled(true);
 view.buildDrawingCache();
 Bitmap b1 = view.getDrawingCache();

// 获取屏幕长和高
 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;
}

这里需要注意: 默认dialog是全屏, activity也是全屏没有状态栏. 如果有状态栏需要获取状态栏大小, 在创建图片的时候减去状态栏大小.

2.将获取的图片进行模糊化, 这里的模糊算法, 是从网上查到, 具体是进行高斯模糊. 具体代码在下面的工具类中.

3.设置模糊图片为dialog的背景


//blurBackgroundDrawer为模糊后的背景图片
Window window = getWindow();
window.setBackgroundDrawable(new BitmapDrawable(mContext.getResources(), blurBackgroundDrawer));

注意: 模糊化图片可能会比较慢, 刚开始测得时候在3 - 4秒之间, 解决办法是将获取到的屏幕进行缩小,然后在进行模糊, 模糊完后, 再将图片放大.

下面是将背景模糊化效果封装成的工具类代码, 使用方法: 只需要将其考到工程中, 在需要模糊化效果的地方调用:
Bitmap bmp = getBlurBackgroundDrawer(activity); 即可.


public class FastBlurUtility {

/**
 * 获得模糊化的背景图片
 * @param activity 获取模糊化的背景activity
 * @return 模糊化的背景图片
 */
public static Bitmap getBlurBackgroundDrawer(Activity activity) {
 Bitmap bmp = takeScreenShot(activity);
 return startBlurBackground(bmp);
}

/**
 * 截屏
 * @param activity 截屏的activity
 * @return 截屏图片
 */
private static Bitmap takeScreenShot(Activity activity) {
 View view = activity.getWindow().getDecorView();
 view.setDrawingCacheEnabled(true);
 view.buildDrawingCache();
 Bitmap b1 = view.getDrawingCache();

// 获取屏幕长和高
 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; //模糊程度

Bitmap overlay = fastblur(small(bkg), (int) radius);

Log.i("FastBlurUtility", "=====blur time:" + (System.currentTimeMillis() - startMs));
 return big(overlay);
}

/**
 * 放大图片
 * @param bitmap 需要放大的图片
 * @return 放大的图片
 */
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;
}

/**
 * 缩小图片
 * @param bitmap 需要缩小的图片
 * @return 缩小的图片
 */
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;
}

/**
 * 将图片模糊化
 * @param sentBitmap 需要模糊的图片
 * @param radius  模糊程度
 * @return 模糊后的图片
 */
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);
}
}

来源:https://blog.csdn.net/lbcab/article/details/51789394

标签:android,dialog,模糊化
0
投稿

猜你喜欢

  • Android IdleHandler使用方法详解

    2023-11-17 20:48:11
  • Android AIDL实现两个APP间的跨进程通信实例

    2022-03-29 08:37:54
  • Android 正则表达式验证手机号、姓名(包含少数民族)、身份证号

    2022-05-26 02:17:11
  • java8新特性将List中按指定属性排序过滤重复数据的方法

    2023-06-16 17:57:42
  • 每日六道java新手入门面试题,通往自由的道路

    2023-11-13 16:22:29
  • C#字体池技术实现代码详解

    2022-12-30 06:18:02
  • C#预处理器指令的用法实例分析

    2023-03-09 16:21:07
  • C#端口转发用法详解

    2022-09-05 08:47:08
  • Java Spring框架简介与Spring IOC详解

    2021-08-06 03:05:56
  • 解决FeignClient发送post请求异常的问题

    2022-08-08 15:55:58
  • Android开发中Intent.Action各种常见的作用汇总

    2022-10-08 10:24:53
  • 判断图片-判断位图是否是黑白图片的方法

    2023-06-09 17:20:07
  • Springboot配置security basic path无效解决方案

    2023-07-12 21:42:50
  • c#委托详解和和示例分享

    2022-10-26 12:29:41
  • Java加载property文件配置过程解析

    2023-10-07 07:53:03
  • IDEA安装详细步骤(多图预警)

    2022-02-28 14:38:39
  • SpringBoot整合rockerMQ消息队列详解

    2021-10-03 10:55:14
  • Java分形绘制山脉模型

    2023-05-10 00:51:29
  • 老生常谈Java中List与ArrayList的区别

    2023-03-26 19:52:33
  • Android AutoCompleteTextView控件基本用法示例

    2022-04-05 08:53:43
  • asp之家 软件编程 m.aspxhome.com