Android 图片虚化,虚化图片,模糊图片
来源:互联网 发布:21天学通c语言第7版pdf 编辑:程序博客网 时间:2024/04/30 08:30
Blur
自从iOS系统引入了Blur效果,也就是所谓的毛玻璃、模糊化效果,磨砂效果,各大系统就开始竞相模仿,这是一个怎样的效果呢,我们现来看一些图:
这些就是典型的Blur效果,在iOS和MIUI中还有很多,这里就不再贴图了。
有兴趣的朋友可以去看看。
使用
下面我们来看看如何在Android中来使用Blur,当然,我们需要使用上面提到的FastBlur
packagecom.xys.blur; importandroid.graphics.Bitmap; /** * Created by paveld on 3/6/14. */public class FastBlur { publicstatic Bitmap doBlur(Bitmap sentBitmap, intradius, booleancanReuseInBitmap) { // 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; if(canReuseInBitmap) { bitmap = sentBitmap; }else{ bitmap = sentBitmap.copy(sentBitmap.getConfig(), true); } if(radius < 1) { return(null); } intw = bitmap.getWidth(); inth = bitmap.getHeight(); int[] pix = newint[w * h]; bitmap.getPixels(pix,0, w, 0,0, w, h); intwm = w - 1; inthm = h - 1; intwh = w * h; intdiv = radius + radius + 1; intr[] = newint[wh]; intg[] = newint[wh]; intb[] = newint[wh]; intrsum, gsum, bsum, x, y, i, p, yp, yi, yw; intvmin[] = newint[Math.max(w, h)]; intdivsum = (div + 1) >> 1; divsum *= divsum; intdv[] = newint[256* divsum]; for(i = 0; i < 256* divsum; i++) { dv[i] = (i / divsum); } yw = yi = 0; int[][] stack = newint[div][3]; intstackpointer; intstackstart; int[] sir; intrbs; intr1 = radius + 1; introutsum, goutsum, boutsum; intrinsum, 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); }}
算法就是这样了,不要问我懂不懂,你懂的。
使用
如何在程序中使用呢,也很简单:
package com.xys.blur; import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.drawable.BitmapDrawable;import android.os.Bundle;import android.view.View;import android.view.ViewTreeObserver.OnPreDrawListener;import android.widget.ImageView; public class Test extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final ImageView imageView = (ImageView) findViewById(R.id.image1); final Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.blur); imageView.getViewTreeObserver().addOnPreDrawListener( new OnPreDrawListener() { @Override public boolean onPreDraw() { blur(bitmap, imageView); return true; } }); } private void blur(Bitmap bkg, View view) { long startMs = System.currentTimeMillis(); float scaleFactor = 8; 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"); }}
为什么我们要在addOnPreDrawListener中来调用blur方法呢,看我前面的文章的朋友应该会知道,这样做是为了能够在onCreate中获取控件尺寸,通过scaleFactor和radius两个参数,我们来控制Blur的程度。
代码中还有几点需要解释下:
1、我们为什么要通过scaleFactor来缩小图片:由于在做Blur的时候,图片精度本来就要降低,那么我们为什么不先降低精度再去处理呢,这样的效果就是巨大的缩小了生成时间
2、我们给Paint提供了FILTER_BITMAP_FLAG标示,这样的话在处理bitmap缩放的时候,就可以达到双缓冲的效果,模糊处理的过程就更加顺畅了
3、如果我们要做某一部分的Blur效果,一般是将这部分图片裁减下来,然后Blur后设给某个控件的背景
最终效果如下:
效果已经出来了,Demo很简单,只是为了演示使用方法。
以上。
0 0
- Android 图片虚化,虚化图片,模糊图片
- android 图片模糊化处理
- iOS -- 图片虚化,模糊化
- 实现图片模糊(背景虚化)
- Android RenderScript模糊图片失败_虚化图片失败_的原因
- 图片模糊化处理
- 图片模糊化处理
- Android生成模糊化背景的图片
- Android 模糊图片技术
- android图片模糊处理
- Android图片模糊处理
- android图片模糊效果
- android 图片模糊解决方案
- Android 生成模糊图片
- 安卓图片模糊化
- iOS 图片背景虚化 高斯模糊
- 图片模糊
- Android fastblur实现图片毛玻璃效果(模糊化)
- 思科IOS中的Ping与traceroute
- The Longest Straight
- Android 颜色对照表
- 如何手工执行segment advisor(10g/11g)
- OC封装 继承 多态
- Android 图片虚化,虚化图片,模糊图片
- 序列化
- 实现不同字体颜色的TextView
- CentOS7系统安装笔记
- OC内存管理
- PageRank算法原理剖析及Spark实现
- Sum is very important!
- shell学习笔记
- 字符集与字符编码的那些事