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


代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
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);
   }

以上就是本文的全部内容,帮助大家轻松实现毛玻璃效果,希望大家喜欢。


    • 1
      点赞
    • 3
      收藏
      觉得还不错? 一键收藏
    • 0
      评论
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值