android实现的毛玻璃效果

jopen 8年前

FastBlur.java文件如下:

package com.example.androidclass;    import android.graphics.Bitmap;      public class FastBlur {        public static Bitmap doBlur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) {                    Bitmap bitmap;          if (canReuseInBitmap) {              bitmap = sentBitmap;          } else {              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++) {                  // Preserve alpha channel: ( 0xff000000 & pix[yi] )                  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);      }  }
MainActivity.java如下:

public class MainActivity extends Activity {     @Override   protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    final ImageView imageView = (ImageView) findViewById(R.id.img_before);      final Bitmap bitmap = BitmapFactory.decodeResource(getResources(),      R.drawable.four);      imageView.getViewTreeObserver().addOnPreDrawListener(      new OnPreDrawListener() {         @Override       public boolean onPreDraw() {        blur(bitmap, imageView);        return true;       }      });   }     @SuppressLint("NewApi")   private void blur(Bitmap bkg, View view) {    long startMs = System.currentTimeMillis();    float scaleFactor = 5;    float radius = 2;      Bitmap overlay = Bitmap.createBitmap(      (int) (view.getMeasuredWidth() / scaleFactor),      (int) (view.getMeasuredHeight() / scaleFactor),      Bitmap.Config.ARGB_8888);    Canvas canvas = new Canvas(overlay);    canvas.translate(-view.getLeft() / scaleFactor, -view.getTop()      / scaleFactor);    canvas.scale(1 / scaleFactor, 1 / scaleFactor);    Paint paint = new Paint();    paint.setFlags(Paint.FILTER_BITMAP_FLAG);    canvas.drawBitmap(bkg, 0, 0, paint);      overlay = FastBlur.doBlur(overlay, (int) radius, true);    view.setBackground(new BitmapDrawable(getResources(), overlay));    System.out.println(System.currentTimeMillis() - startMs + "ms");   }  }

源码下载: http://download.csdn.net/detail/mockingbirds/8151143

来自: http://blog.csdn.net//mockingbirds/article/details/41053121