Android模糊处理实现图片毛玻璃效果

本文实例讲解了Android 虚化图片、模糊图片、图片毛玻璃效果的实现方法,具体内容如下

效果如图:

在Android可以用RenderScript方便的实现这个方法:

private void blur(Bitmap bkg, View view, float radius) {
  Bitmap overlay = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
  Canvas canvas = new Canvas(overlay);
  canvas.drawBitmap(bkg, -view.getLeft(), -view.getTop(), null);
  RenderScript rs = RenderScript.create(this);
  Allocation overlayAlloc = Allocation.createFromBitmap(rs, overlay);
  ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, overlayAlloc.getElement());
  blur.setInput(overlayAlloc);
  blur.setRadius(radius);
  blur.forEach(overlayAlloc);
  overlayAlloc.copyTo(overlay);
  view.setBackground(new BitmapDrawable(getResources(), overlay));
  rs.destroy();
 }

但是RenderScript的这个方法需要Android API17,也就说需要在Android 4.2上才能实现。
低于Android4.2可以用Java原生代码实现。但是效率会低不少:这完全是一种妥协的方式,不推荐。

/*
  * This method was copied from http://stackoverflow.com/a/10028267/694378.
  * The only modifications I've made are to remove a couple of Log
  * statements which could slow things down slightly.
  */
 public Bitmap fastblur(Bitmap sentBitmap, int radius) { 

  // Stack Blur v1.0 from
  // http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html
  //
  // Java Author: Mario Klingemann <mario at quasimondo.com>
  // http://incubator.quasimondo.com
  // created Feburary 29, 2004
  // Android port : Yahel Bouaziz <yahel at kayenko.com>
  // http://www.kayenko.com
  // ported april 5th, 2012 

  // This is a compromise between Gaussian Blur and Box blur
  // It creates much better looking blurs than Box Blur, but is
  // 7x faster than my Gaussian Blur implementation.
  //
  // I called it Stack Blur because this describes best how this
  // filter works internally: it creates a kind of moving stack
  // of colors whilst scanning through the image. Thereby it
  // just has to add one new block of color to the right side
  // of the stack and remove the leftmost color. The remaining
  // colors on the topmost layer of the stack are either added on
  // or reduced by one, depending on if they are on the right or
  // on the left side of the stack.
  //
  // If you are using this algorithm in your code please add
  // the following line:
  //
  // Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com> 

  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++) {
    // 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);
 } 

以上就是本文的全部内容,希望对大家学习Android软件编程有所帮助。

(0)

相关推荐

  • Android实现图片的高斯模糊(两种方式)

    在市面上很多的APP都使用了对图片作模糊化处理后作为背景的效果,来使得整个页面更具有整体感.如下就是网易云音乐的音乐播放页面: 很明显这个页面的背景是由中间的小图片模糊化后而来的.最常用的模糊化处理就是高斯模糊. 高斯模糊的几种实现方式: (1)RenderScript RenderScript是Google在Android 3.0(API 11)中引入的一个高性能图片处理框架. 使用RenderScriprt实现高斯模糊: 首先在在build.gradle的defaultConfig中添加Re

  • Android调用系统拍照裁剪图片模糊的解决方法

    在Android中,调用系统相机拍照时,将会接收到返回的图像数据,但是这些图片并不是全尺寸的图像,而是系统给的缩略图,当对拍照的图片进行裁切后显示时,得到的却是模糊的图片.下面针对这个问题提出解决的方法. 首先,我们知道调用系统的裁切是通过Intent intent = new Intent("com.android.camera.action.CROP"); 但是intent到底能够携带哪些数据呢,都有什么含义呢,我们可以看到如下: 上面包含了所有可选的操作,其中有一些非常重要的参数

  • Android图片特效:黑白特效、圆角效果、高斯模糊

    1.黑白效果 复制代码 代码如下: /**     * 将彩色图转换为黑白图     *      * @param 位图     * @return 返回转换好的位图     */    public static Bitmap convertToBlackWhite(Bitmap bmp) {        int width = bmp.getWidth(); // 获取位图的宽        int height = bmp.getHeight(); // 获取位图的高 int[] pi

  • Android中实现布局背景模糊化处理的方法

    在模仿 IOS 密码输入页面的时候发现其背景有模糊处理,于是了解了一下并记录下来,以便使用.在Android 中具体实现方法如下 查考 http://www.jb51.net/article/64781.htm private void applyBlur() { // 获取壁纸管理器 WallpaperManager wallpaperManager = WallpaperManager.getInstance(this.getContext()); // 获取当前壁纸 Drawable wa

  • Android实现局部模糊效果

    本文实例为大家分享了Android实现局部模糊效果展示的具体代码,供大家参考,具体内容如下 要实现模糊或者毛玻璃效果,使用PS自然最方便(模糊的区域就较为固定): 也可在代码里进行动态处理. 因为要模糊的区域并不固定,所以只能琢磨一下后者: 经过一番搜寻研究,得到两种切实可行的方法. 一.使用FastBlur: 二.使用RenderScript. 效果如下: 算法 1.FastBlur /** * 高斯模糊 * * @param srcBitmap * 源位图 * @param radius *

  • Android实现动态高斯模糊效果

    高斯模糊是什么? 高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop.GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪声以及降低细节层次.这种模糊技术生成的图像,其视觉效果就像是经过一个半透明屏幕在观察图像,这与镜头焦外成像效果散景以及普通照明阴影中的效果都明显不同. 什么?看不明白?没关系,我也看不明白,维基百科复制回来的嘛.我们直接放一些图片来了解以下这个高斯模糊是怎么样的.因为高斯模糊在iOS中最常见,这里抓

  • Android 实现图片模糊、高斯模糊、毛玻璃效果的三种方法

    在前几天写过一个使用glide-transformations的方法实现高斯模糊的方法,今天偶然间有发现一个大神写的另一个方法,感觉挺不错的,分享一下: 效果图: 原文链接:点击访问 这使用也很简单,导入依赖,使用模糊方法就行,就这两步搞定 依赖: compile 'net.qiujuer.genius:blur:2.0.0-beta4' 实现方法有三种,第一个是Java实现的,第二个和第三个是调用C语言实现的 ,具体的区别也就是代码执行的耗时操作时间,从图片中可以看出Java使用时间远大于c运

  • Android实现个人资料页面头像背景模糊显示包(状态栏)

    最近要实现这样一个效果,然后拿出来与大家分享一下主要的几段代码,希望大家能够用到,与人方便自己方便嘛! 首先: 要实现的是浮动状态栏效果,通过在Activity的onCreate方法中调用这个方法,然后就可以让整个布局浮现在整个手机屏幕之下了,这是我觉着最简单的一种方法了. public static void alphaTask(Activity context) { context.getWindow().requestFeature(Window.FEATURE_NO_TITLE); if

  • Android关于Glide的使用(高斯模糊、加载监听、圆角图片)

    高斯模糊.加载监听.圆角图片这些相信大家都很熟悉,那如何实现这些效果,请大家参考本文进行学习. 1.引用 compile 'com.github.bumptech.glide:glide:3.7.0' 2.加载图片 2.1 基本加载 Glide.with(context)     .load(url)     .into(imageView); 2.2 设置加载中和加载失败的情况 Glide.with(context) .load(url) .placeholder(R.drawable.loa

  • Android模糊处理简单实现毛玻璃效果

    自从iOS系统引入了Blur效果,也就是所谓的毛玻璃.模糊化效果.磨砂效果,各大系统就开始竞相模仿,这是怎样的一个效果呢,我们先来看一下,如下面的图片: 实现效果大家都知道了,如何在Android中实现呢,说白了就是对图片进行模糊化处理,小编先给大家讲一下Android高级模糊技术的原理,如下: 首先我创建了一个空的bitmap,把背景的一部分复制进去,之后我会对这个bitmap进行模糊处理并设置为TextView的背景. 通过这个bitmap保存Canvas的状态: 在父布局文件中把Canva

随机推荐