使用:
1.在执行弹出界面前,先将其当前屏幕截图。
1 BlurBuilder.snapShotWithoutStatusBar(getActivity());
2.为了确保界面切入无效果。
1 startActivity(wechatIntent); 2 context.overridePendingTransition( 3 android.view.animation.Animation.INFINITE, 4 android.view.animation.Animation.INFINITE);
3.在切换的页面中初始化背景ImageView:
1 private void applyBlur() { 2 iv_shared_layout.setImageBitmap(BlurBuilder.blur(iv_shared_layout)); 3 if (BlurBuilder.isBlurFlag()) { 4 iv_shared_layout.setVisibility(View.VISIBLE); 5 } 6 }
4.在acitivity的super.finish();或者在onDestroy中回收资源:
1 @Override 2 public void finish() { 3 defaultFinishNotActivityHelper(); 4 BlurBuilder.recycle(); 5 overridePendingTransition(android.view.animation.Animation.INFINITE, 6 android.view.animation.Animation.INFINITE); 7 }
毛玻璃模糊效果使用类:
1 public class BlurBuilder { 2 3 private static final float BITMAP_SCALE = 0.4f; 4 private static final float BLUR_RADIUS = 7.5f; 5 6 private static Bitmap tab_bg = null; 7 private static Bitmap overlay = null; 8 private static boolean blurFlag = false; 9 10 public static boolean isBlurFlag() { 11 return BlurBuilder.blurFlag; 12 } 13 14 public static void setBlurFlag(boolean blurFlag) { 15 BlurBuilder.blurFlag = blurFlag; 16 } 17 18 public static Bitmap blur(View v) { 19 if (tab_bg == null) { 20 android.util.Log.i("", "tab_bg == null"); 21 blurFlag = false; 22 return null; 23 } 24 blurFlag = true; 25 blur(v.getContext(), tab_bg); 26 return overlay; 27 } 28 29 public static void blur(Context ctx, Bitmap image) { 30 if (overlay != null) { 31 recycle(); 32 } 33 try { 34 int width = Math.round(image.getWidth() * BITMAP_SCALE); 35 int height = Math.round(image.getHeight() * BITMAP_SCALE); 36 37 overlay = Bitmap.createScaledBitmap(image, (int) (width), 38 (int) (height), false); 39 40 overlay = FastBlur.doBlur(overlay, (int) BLUR_RADIUS, true); 41 } catch (Exception e) { 42 e.printStackTrace(); 43 } 44 } 45 46 public static void getScreenshot(View v) { 47 if (tab_bg != null) { 48 recycle(); 49 } 50 try { 51 tab_bg = Bitmap.createBitmap(v.getWidth(), v.getHeight(), 52 Bitmap.Config.RGB_565); 53 Canvas c = new Canvas(tab_bg); 54 v.draw(c); 55 } catch (Exception e) { 56 e.printStackTrace(); 57 } 58 } 59 60 /** 61 * 获取当前屏幕截图,不包含状态栏 62 * 63 * @param activity 64 * @return 65 */ 66 public static void snapShotWithoutStatusBar(Activity activity) { 67 if (tab_bg != null) { 68 recycle(); 69 } 70 View view = activity.getWindow().getDecorView(); 71 try { 72 view.setDrawingCacheEnabled(true); 73 view.buildDrawingCache(); 74 tab_bg = view.getDrawingCache(); 75 Rect frame = new Rect(); 76 activity.getWindow().getDecorView() 77 .getWindowVisibleDisplayFrame(frame); 78 int statusBarHeight = frame.top; 79 80 int width = ScreenUtils.getScreenWidth(activity); 81 int height = ScreenUtils.getScreenHeight(activity); 82 tab_bg = Bitmap.createBitmap(tab_bg, 0, statusBarHeight, width, 83 height - statusBarHeight); 84 view.destroyDrawingCache(); 85 } catch (Exception e) { 86 e.printStackTrace(); 87 getScreenshot(view); 88 } 89 } 90 91 public static void recycle() { 92 93 try { 94 if (tab_bg != null) { 95 tab_bg.recycle(); 96 System.gc(); 97 tab_bg = null; 98 } 99 if (overlay != null) { 100 overlay.recycle(); 101 System.gc(); 102 overlay = null; 103 } 104 } catch (Exception e) { 105 e.printStackTrace(); 106 } 107 } 108 }
毛玻璃模糊效果类:
1 public class FastBlur { 2 3 public static Bitmap doBlur(Bitmap sentBitmap, int radius, 4 boolean canReuseInBitmap) { 5 6 Bitmap bitmap; 7 if (canReuseInBitmap) { 8 bitmap = sentBitmap; 9 } else { 10 bitmap = sentBitmap.copy(sentBitmap.getConfig(), true); 11 } 12 13 if (radius < 1) { 14 return (null); 15 } 16 17 int w = bitmap.getWidth(); 18 int h = bitmap.getHeight(); 19 20 int[] pix = new int[w * h]; 21 bitmap.getPixels(pix, 0, w, 0, 0, w, h); 22 23 int wm = w - 1; 24 int hm = h - 1; 25 int wh = w * h; 26 int div = radius + radius + 1; 27 28 int r[] = new int[wh]; 29 int g[] = new int[wh]; 30 int b[] = new int[wh]; 31 int rsum, gsum, bsum, x, y, i, p, yp, yi, yw; 32 int vmin[] = new int[Math.max(w, h)]; 33 34 int divsum = (div + 1) >> 1; 35 divsum *= divsum; 36 int dv[] = new int[256 * divsum]; 37 for (i = 0; i < 256 * divsum; i++) { 38 dv[i] = (i / divsum); 39 } 40 41 yw = yi = 0; 42 43 int[][] stack = new int[div][3]; 44 int stackpointer; 45 int stackstart; 46 int[] sir; 47 int rbs; 48 int r1 = radius + 1; 49 int routsum, goutsum, boutsum; 50 int rinsum, ginsum, binsum; 51 52 for (y = 0; y < h; y++) { 53 rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; 54 for (i = -radius; i <= radius; i++) { 55 p = pix[yi + Math.min(wm, Math.max(i, 0))]; 56 sir = stack[i + radius]; 57 sir[0] = (p & 0xff0000) >> 16; 58 sir[1] = (p & 0x00ff00) >> 8; 59 sir[2] = (p & 0x0000ff); 60 rbs = r1 - Math.abs(i); 61 rsum += sir[0] * rbs; 62 gsum += sir[1] * rbs; 63 bsum += sir[2] * rbs; 64 if (i > 0) { 65 rinsum += sir[0]; 66 ginsum += sir[1]; 67 binsum += sir[2]; 68 } else { 69 routsum += sir[0]; 70 goutsum += sir[1]; 71 boutsum += sir[2]; 72 } 73 } 74 stackpointer = radius; 75 76 for (x = 0; x < w; x++) { 77 78 r[yi] = dv[rsum]; 79 g[yi] = dv[gsum]; 80 b[yi] = dv[bsum]; 81 82 rsum -= routsum; 83 gsum -= goutsum; 84 bsum -= boutsum; 85 86 stackstart = stackpointer - radius + div; 87 sir = stack[stackstart % div]; 88 89 routsum -= sir[0]; 90 goutsum -= sir[1]; 91 boutsum -= sir[2]; 92 93 if (y == 0) { 94 vmin[x] = Math.min(x + radius + 1, wm); 95 } 96 p = pix[yw + vmin[x]]; 97 98 sir[0] = (p & 0xff0000) >> 16; 99 sir[1] = (p & 0x00ff00) >> 8; 100 sir[2] = (p & 0x0000ff); 101 102 rinsum += sir[0]; 103 ginsum += sir[1]; 104 binsum += sir[2]; 105 106 rsum += rinsum; 107 gsum += ginsum; 108 bsum += binsum; 109 110 stackpointer = (stackpointer + 1) % div; 111 sir = stack[(stackpointer) % div]; 112 113 routsum += sir[0]; 114 goutsum += sir[1]; 115 boutsum += sir[2]; 116 117 rinsum -= sir[0]; 118 ginsum -= sir[1]; 119 binsum -= sir[2]; 120 121 yi++; 122 } 123 yw += w; 124 } 125 for (x = 0; x < w; x++) { 126 rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; 127 yp = -radius * w; 128 for (i = -radius; i <= radius; i++) { 129 yi = Math.max(0, yp) + x; 130 131 sir = stack[i + radius]; 132 133 sir[0] = r[yi]; 134 sir[1] = g[yi]; 135 sir[2] = b[yi]; 136 137 rbs = r1 - Math.abs(i); 138 139 rsum += r[yi] * rbs; 140 gsum += g[yi] * rbs; 141 bsum += b[yi] * rbs; 142 143 if (i > 0) { 144 rinsum += sir[0]; 145 ginsum += sir[1]; 146 binsum += sir[2]; 147 } else { 148 routsum += sir[0]; 149 goutsum += sir[1]; 150 boutsum += sir[2]; 151 } 152 153 if (i < hm) { 154 yp += w; 155 } 156 } 157 yi = x; 158 stackpointer = radius; 159 for (y = 0; y < h; y++) { 160 // Preserve alpha channel: ( 0xff000000 & pix[yi] ) 161 pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) 162 | (dv[gsum] << 8) | dv[bsum]; 163 164 rsum -= routsum; 165 gsum -= goutsum; 166 bsum -= boutsum; 167 168 stackstart = stackpointer - radius + div; 169 sir = stack[stackstart % div]; 170 171 routsum -= sir[0]; 172 goutsum -= sir[1]; 173 boutsum -= sir[2]; 174 175 if (x == 0) { 176 vmin[y] = Math.min(y + r1, hm) * w; 177 } 178 p = x + vmin[y]; 179 180 sir[0] = r[p]; 181 sir[1] = g[p]; 182 sir[2] = b[p]; 183 184 rinsum += sir[0]; 185 ginsum += sir[1]; 186 binsum += sir[2]; 187 188 rsum += rinsum; 189 gsum += ginsum; 190 bsum += binsum; 191 192 stackpointer = (stackpointer + 1) % div; 193 sir = stack[stackpointer]; 194 195 routsum += sir[0]; 196 goutsum += sir[1]; 197 boutsum += sir[2]; 198 199 rinsum -= sir[0]; 200 ginsum -= sir[1]; 201 binsum -= sir[2]; 202 203 yi += w; 204 } 205 } 206 207 bitmap.setPixels(pix, 0, w, 0, 0, w, h); 208 209 return (bitmap); 210 } 211 }