zoukankan      html  css  js  c++  java
  • 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技术和程序员工作心得体会。

    欢迎大家关注与转载。



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





  • 相关阅读:
    【技术评网】说说豆瓣的URL设计
    在这一刻,还是忍不住满眼泪水
    装Sybase,装WAS 6.1的时候报错java.exe损坏的图象
    JasperRepor导出报表通用类
    XSS跨站攻击
    sql 脚本
    解决在无线网络下本机无法连接linux(红帽)虚拟机问题
    pl /sql导入导出表结构,表数据,sql脚本
    asp.net关于WEB端用户重复提交问题。禁用服务器控件按钮问题。
    MQ命令学习总结大全MQ常用命令
  • 原文地址:https://www.cnblogs.com/llguanli/p/7106318.html
Copyright © 2011-2022 走看看