前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android如何实现毛玻璃效果之Android高级模糊技术

Android如何实现毛玻璃效果之Android高级模糊技术

作者头像
非著名程序员
发布2018-02-01 16:21:48
2.7K0
发布2018-02-01 16:21:48
举报
文章被收录于专栏:非著名程序员非著名程序员

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以上,可以使用系统提供的方法直接处理图片,但是小编认为下边的解决方案是实现效果最好的。 代码如下:

代码语言:js
复制
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);
 }
代码实现的效果图如下:
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2015-07-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 非著名程序员 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档