1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:id="@+id/relative" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 android:background="@drawable/screenshot" > 7 8 </RelativeLayout>
1 package com.example.hairglassbackdemo; 2 3 import android.annotation.TargetApi; 4 import android.app.Activity; 5 import android.graphics.Bitmap; 6 import android.graphics.Canvas; 7 import android.graphics.Paint; 8 import android.graphics.Rect; 9 import android.graphics.drawable.BitmapDrawable; 10 import android.os.Build; 11 import android.os.Bundle; 12 import android.support.v7.app.ActionBarActivity; 13 import android.util.Log; 14 import android.view.View; 15 16 @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 17 public class MainActivity extends ActionBarActivity { 18 19 private Bitmap bitmap; 20 21 @Override 22 protected void onCreate(Bundle savedInstanceState) { 23 super.onCreate(savedInstanceState); 24 setContentView(R.layout.activity_main); 25 } 26 27 @Override 28 public void onWindowFocusChanged(boolean hasFocus) { 29 super.onWindowFocusChanged(hasFocus); 30 if (null == bitmap) { 31 // 需要在actvity显示出来后 再进行截屏操作。这里进行模糊化图片是个耗时操作,建议在项目中放到非UI线程去做 32 bitmap = takeScreenShot(MainActivity.this); 33 } 34 35 if (bitmap != null) { 36 37 blur(bitmap, findViewById(R.id.relative)); 38 } 39 } 40 41 /** 42 * 屏幕截图 43 * 44 * @param activity 45 * @return 46 */ 47 private Bitmap takeScreenShot(Activity activity) { 48 // View是你需要截图的View 49 View view = activity.getWindow().getDecorView(); 50 view.setDrawingCacheEnabled(true); 51 view.buildDrawingCache(); 52 Bitmap b1 = view.getDrawingCache(); 53 54 // 获取状态栏高度 55 Rect frame = new Rect(); 56 activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame); 57 int statusBarHeight = frame.top; 58 59 // 获取屏幕长和高 60 int width = activity.getWindowManager().getDefaultDisplay().getWidth(); 61 int height = activity.getWindowManager().getDefaultDisplay() 62 .getHeight(); 63 // 去掉标题栏 64 // Bitmap b = Bitmap.createBitmap(b1, 0, 25, 320, 455); 65 Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height 66 - statusBarHeight); 67 view.destroyDrawingCache(); 68 return b; 69 } 70 71 72 private void blur(Bitmap bkg, View view) { 73 long startMs = System.currentTimeMillis(); 74 float radius = 2; 75 float scaleFactor = 8; 76 77 Bitmap overlay = Bitmap.createBitmap( 78 (int) (view.getMeasuredWidth() / scaleFactor), 79 (int) (view.getMeasuredHeight() / scaleFactor), 80 Bitmap.Config.ARGB_8888); 81 Canvas canvas = new Canvas(overlay); 82 canvas.translate(-view.getLeft() / scaleFactor, -view.getTop() 83 / scaleFactor); 84 canvas.scale(1 / scaleFactor, 1 / scaleFactor); 85 Paint paint = new Paint(); 86 paint.setFlags(Paint.FILTER_BITMAP_FLAG); 87 canvas.drawBitmap(bkg, 0, 0, paint); 88 overlay = FastBlur.doBlur(overlay, (int) radius, true); 89 view.setBackground(new BitmapDrawable(getResources(), overlay)); 90 Log.e("Blur", "cost " + (System.currentTimeMillis() - startMs) + "ms"); 91 } 92 }
1 package com.example.hairglassbackdemo; 2 3 import android.graphics.Bitmap; 4 5 public class FastBlur { 6 public static Bitmap doBlur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) { 7 8 // Stack Blur v1.0 from 9 // http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html 10 // 11 // Java Author: Mario Klingemann <mario at="" quasimondo.com=""> 12 // http://incubator.quasimondo.com 13 // created Feburary 29, 2004 14 // Android port : Yahel Bouaziz <yahel at="" kayenko.com=""> 15 // http://www.kayenko.com 16 // ported april 5th, 2012 17 18 // This is a compromise between Gaussian Blur and Box blur 19 // It creates much better looking blurs than Box Blur, but is 20 // 7x faster than my Gaussian Blur implementation. 21 // 22 // I called it Stack Blur because this describes best how this 23 // filter works internally: it creates a kind of moving stack 24 // of colors whilst scanning through the image. Thereby it 25 // just has to add one new block of color to the right side 26 // of the stack and remove the leftmost color. The remaining 27 // colors on the topmost layer of the stack are either added on 28 // or reduced by one, depending on if they are on the right or 29 // on the left side of the stack. 30 // 31 // If you are using this algorithm in your code please add 32 // the following line: 33 // 34 // Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com> 35 36 Bitmap bitmap; 37 if (canReuseInBitmap) { 38 bitmap = sentBitmap; 39 } else { 40 bitmap = sentBitmap.copy(sentBitmap.getConfig(), true); 41 } 42 43 if (radius < 1) { 44 return (null); 45 } 46 47 int w = bitmap.getWidth(); 48 int h = bitmap.getHeight(); 49 50 int[] pix = new int[w * h]; 51 bitmap.getPixels(pix, 0, w, 0, 0, w, h); 52 53 int wm = w - 1; 54 int hm = h - 1; 55 int wh = w * h; 56 int div = radius + radius + 1; 57 58 int r[] = new int[wh]; 59 int g[] = new int[wh]; 60 int b[] = new int[wh]; 61 int rsum, gsum, bsum, x, y, i, p, yp, yi, yw; 62 int vmin[] = new int[Math.max(w, h)]; 63 64 int divsum = (div + 1) >> 1; 65 divsum *= divsum; 66 int dv[] = new int[256 * divsum]; 67 for (i = 0; i < 256 * divsum; i++) { 68 dv[i] = (i / divsum); 69 } 70 71 yw = yi = 0; 72 73 int[][] stack = new int[div][3]; 74 int stackpointer; 75 int stackstart; 76 int[] sir; 77 int rbs; 78 int r1 = radius + 1; 79 int routsum, goutsum, boutsum; 80 int rinsum, ginsum, binsum; 81 82 for (y = 0; y < h; y++) { 83 rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; 84 for (i = -radius; i <= radius; i++) { 85 p = pix[yi + Math.min(wm, Math.max(i, 0))]; 86 sir = stack[i + radius]; 87 sir[0] = (p & 0xff0000) >> 16; 88 sir[1] = (p & 0x00ff00) >> 8; 89 sir[2] = (p & 0x0000ff); 90 rbs = r1 - Math.abs(i); 91 rsum += sir[0] * rbs; 92 gsum += sir[1] * rbs; 93 bsum += sir[2] * rbs; 94 if (i > 0) { 95 rinsum += sir[0]; 96 ginsum += sir[1]; 97 binsum += sir[2]; 98 } else { 99 routsum += sir[0]; 100 goutsum += sir[1]; 101 boutsum += sir[2]; 102 } 103 } 104 stackpointer = radius; 105 106 for (x = 0; x < w; x++) { 107 108 r[yi] = dv[rsum]; 109 g[yi] = dv[gsum]; 110 b[yi] = dv[bsum]; 111 112 rsum -= routsum; 113 gsum -= goutsum; 114 bsum -= boutsum; 115 116 stackstart = stackpointer - radius + div; 117 sir = stack[stackstart % div]; 118 119 routsum -= sir[0]; 120 goutsum -= sir[1]; 121 boutsum -= sir[2]; 122 123 if (y == 0) { 124 vmin[x] = Math.min(x + radius + 1, wm); 125 } 126 p = pix[yw + vmin[x]]; 127 128 sir[0] = (p & 0xff0000) >> 16; 129 sir[1] = (p & 0x00ff00) >> 8; 130 sir[2] = (p & 0x0000ff); 131 132 rinsum += sir[0]; 133 ginsum += sir[1]; 134 binsum += sir[2]; 135 136 rsum += rinsum; 137 gsum += ginsum; 138 bsum += binsum; 139 140 stackpointer = (stackpointer + 1) % div; 141 sir = stack[(stackpointer) % div]; 142 143 routsum += sir[0]; 144 goutsum += sir[1]; 145 boutsum += sir[2]; 146 147 rinsum -= sir[0]; 148 ginsum -= sir[1]; 149 binsum -= sir[2]; 150 151 yi++; 152 } 153 yw += w; 154 } 155 for (x = 0; x < w; x++) { 156 rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; 157 yp = -radius * w; 158 for (i = -radius; i <= radius; i++) { 159 yi = Math.max(0, yp) + x; 160 161 sir = stack[i + radius]; 162 163 sir[0] = r[yi]; 164 sir[1] = g[yi]; 165 sir[2] = b[yi]; 166 167 rbs = r1 - Math.abs(i); 168 169 rsum += r[yi] * rbs; 170 gsum += g[yi] * rbs; 171 bsum += b[yi] * rbs; 172 173 if (i > 0) { 174 rinsum += sir[0]; 175 ginsum += sir[1]; 176 binsum += sir[2]; 177 } else { 178 routsum += sir[0]; 179 goutsum += sir[1]; 180 boutsum += sir[2]; 181 } 182 183 if (i < hm) { 184 yp += w; 185 } 186 } 187 yi = x; 188 stackpointer = radius; 189 for (y = 0; y < h; y++) { 190 // Preserve alpha channel: ( 0xff000000 & pix[yi] ) 191 pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum]; 192 193 rsum -= routsum; 194 gsum -= goutsum; 195 bsum -= boutsum; 196 197 stackstart = stackpointer - radius + div; 198 sir = stack[stackstart % div]; 199 200 routsum -= sir[0]; 201 goutsum -= sir[1]; 202 boutsum -= sir[2]; 203 204 if (x == 0) { 205 vmin[y] = Math.min(y + r1, hm) * w; 206 } 207 p = x + vmin[y]; 208 209 sir[0] = r[p]; 210 sir[1] = g[p]; 211 sir[2] = b[p]; 212 213 rinsum += sir[0]; 214 ginsum += sir[1]; 215 binsum += sir[2]; 216 217 rsum += rinsum; 218 gsum += ginsum; 219 bsum += binsum; 220 221 stackpointer = (stackpointer + 1) % div; 222 sir = stack[stackpointer]; 223 224 routsum += sir[0]; 225 goutsum += sir[1]; 226 boutsum += sir[2]; 227 228 rinsum -= sir[0]; 229 ginsum -= sir[1]; 230 binsum -= sir[2]; 231 232 yi += w; 233 } 234 } 235 236 bitmap.setPixels(pix, 0, w, 0, 0, w, h); 237 238 return (bitmap); 239 } 240 }