当前位置: 代码迷 >> Android >> Android怎么实现毛玻璃效果之Android高级模糊技术
  详细解决方案

Android怎么实现毛玻璃效果之Android高级模糊技术

热度:81   发布时间:2016-04-28 00:11:55.0
Android如何实现毛玻璃效果之Android高级模糊技术

自从iOS系统引入了Blur效果,也就是所谓的毛玻璃、模糊化效果,磨砂效果,各大系统就开始竞相模仿,这是怎样的一个效果呢,我们先来看一下,如下面的图片:

效果我们知道了,如何在Android中实现呢,说白了就是对图片进行模糊化处理,小编先给大家讲一下Android高级模糊技术的原理,如下:

·首先我创建了一个空的bitmap,把背景的一部分复制进去,之后我会对这个bitmap进行模糊处理并设置为TextView的背景。

·通过这个bitmap保存Canvas的状态;

·在父布局文件中把Canvas移动到TextView的位置;

·把ImageView的内容绘到bitmap中;

·此时,我们就有了一个和TextView一样大小的bitmap,它包含了ImageView的一部分内容,也就是TextView背后一层布局的内容;

·创建一个Renderscript的实例;

·把bitmap复制一份到Renderscript需要的数据片中;

·创建Renderscript模糊处理的实例;

·设置输入,半径范围然后进行模糊处理;

·把处理后的结果复制回之前的bitmap中;

·好了,我们已经把bitmap惊醒模糊处理了,可以将它设置为TextView背景了;

我最近在做一款App,其中有一个功能需要对图片处理实现毛玻璃的特效,经过一番研究,找到了3中实现方案,其中各有优缺点,如果系统的api在16以上,可以使用系统提供的方法直接处理图片,但是小编认为下边的解决方案是实现效果最好的。

代码如下:

public Bitmap fastblur(Context context, Bitmap sentBitmap, int radius) {		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 temp = 256 * divsum;		int dv[] = new int[temp];		for (i = 0; i < temp; 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++) {				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);	}

代码实现的效果图如下:


如果想要源码,请大家多多支持,分享到朋友圈,发送分享到朋友圈后的截屏和邮箱到此公众号,小编会争取第一时间把源码发送给您。


微信号:smart_android (←长按复制)

介绍:非著名程序员,字耿左直右,号涩郎,爱搞机,爱编程,是爬行在移动互联网中的一名码匠!

个人微信号:loonggg

微博:涩郎

QQ群:413589216 更能资料和源码尽在QQ群文件

今日头条:搜索“非著名程序员”订阅更多信息

工作:专注于移动互联网的开发和研究,本号致力于分享IT技术和程序猿工作心得体会。欢迎大家关注与转载。



众多开发视频教程尽在本公众号,关注此公众号,在菜单中点击干货资料,选择视频教程即可获取下载网址。





版权声明:本文为博主原创文章,未经博主允许不得转载。

  相关解决方案