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);
  }

以上就是本文的全部內容,幫助大家輕鬆實現毛玻璃效果,希望大家喜歡。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章