android 滑动模糊渐变,Android UI效果实现 滑动模糊渐变效果实现

大家应该都看到过iOS7解锁屏幕的滑动模糊渐变效果,好了,现在可以把手纸收起来了,今天黄老师就给大家讲一下如何在Android平台上

实现类似的滑动模糊渐变效果,其实方式远比你想像的简单。

目标效果展示:

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

第一部分:几个前提

说到模糊效果,我们先要了解几个前提

1、原图,指需要被模糊的一张位图

2、模糊,通常是采用指将一个位图的每个像素RGB值都取周围像素的RGB值的平均值,这样就可以产生模糊效果,一般通过高斯函数来实现,

至于Java中的实现方式黄老师就不给大家细讲了,我也不是搞图形算法的,在这方面了解的不比大家多,百度一下能找到一堆高斯模糊转换的实现。

3、模糊半径,指每个像素点周围模糊的半径,半径越大,模糊程度约高,模糊效果越明显,同时,模糊计算耗费时间越长。

4、模糊处理非常费时,一半在100ms~5000ms内,就黄老师我本人找的网上的算法实测,一般android通过java实现的高斯模糊算法转换一张手机

屏幕分辨率为480x800的位图需要2s左右,所以如果要在滑动的过程中实时不断重新计算模糊效果会非常差,所以如果要实现iOS7那样的滑动动态模糊

渐变效果,用这样的方式是不可行的,实际上iOS也不是这么做的,因为iOS的硬件也没达到能实时计算的程度。

那么究竟应该如何去实现模糊渐变呢,其实非常简单,我们接着讲。

第二部分:动态模糊渐变的合理实现方式

其实,我的方式非常简单,首先你需要明确一个最大的模糊效果的模糊半径值,我们给它取个名字叫maxRadius,然后使用maxRadius和原图传入高斯模糊算法

中计算出最大模糊效果的位图maxBlurBitmap。

然后,在ui组件中,假设我的原图是用一个ImageView显示在界面上的,然后你所需要做的是,再创建一个ImageView置于原图ImageView之上,然后将图片源

设置为maxBlurBitmap,如下图:

0818b9ca8b590ca3270a3433284dd417.png

接着,我们只需要简单的调整maxBlurBitmap的透明度,即可实现模糊渐变效果了,是否很简单呢?

第三部分,提供一个最简单的Java高斯模糊实现,我网上找来的,方便偷懒不愿自己找的同学

001.

1 /**

002.

2  * 位图处理类

003.

3  * @author HalfmanG2

004.

4  */

005.

5 public class BitmapUtil {

006.

6

007.

7     /**

008.

8      * 创建一个虚化的位图

009.

9      * @param sentBitmap 原位图

010.

10      * @param radius 虚化半径

011.

11      * @return 虚化后的位图

012.

12      */

013.

13     public static Bitmap createBlurBitmap(Bitmap sentBitmap,int radius) {

014.

14         Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(),true);

015.

15         if (radius <1) {

016.

16             return (null);

017.

17         }

018.

18         int w = bitmap.getWidth();

019.

19         int h = bitmap.getHeight();

020.

20         int[] pix =new int[w * h];

021.

21         bitmap.getPixels(pix,0, w,0,0, w, h);

022.

22         int wm = w -1;

023.

23         int hm = h -1;

024.

24         int wh = w * h;

025.

25         int div = radius + radius +1;

026.

26         int r[] =new int[wh];

027.

27         int g[] =new int[wh];

028.

28         int b[] =new int[wh];

029.

29         int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;

030.

30         int vmin[] =new int[Math.max(w, h)];

031.

31         int divsum = (div +1) >>1;

032.

32         divsum *= divsum;

033.

33         int dv[] =new int[256 * divsum];

034.

34         for (i =0; i <256 * divsum; i++) {

035.

35             dv[i] = (i / divsum);

036.

36         }

037.

37         yw = yi =0;

038.

38         int[][] stack =new int[div][3];

039.

39         int stackpointer;

040.

40         int stackstart;

041.

41         int[] sir;

042.

42         int rbs;

043.

43         int r1 = radius +1;

044.

44         int routsum, goutsum, boutsum;

045.

45         int rinsum, ginsum, binsum;

046.

46         for (y =0; y < h; y++) {

047.

47             rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum =0;

048.

48             for (i = -radius; i <= radius; i++) {

049.

49                 p = pix[yi + Math.min(wm, Math.max(i,0))];

050.

50                 sir = stack[i + radius];

051.

51                 sir[0] = (p &0xff0000) >>16;

052.

52                 sir[1] = (p &0x00ff00) >>8;

053.

53                 sir[2] = (p &0x0000ff);

054.

54                 rbs = r1 - Math.abs(i);

055.

55                 rsum += sir[0] * rbs;

056.

56                 gsum += sir[1] * rbs;

057.

57                 bsum += sir[2] * rbs;

058.

58                 if (i >0) {

059.

59                     rinsum += sir[0];

060.

60                     ginsum += sir[1];

061.

61                     binsum += sir[2];

062.

62                 }else {

063.

63                     routsum += sir[0];

064.

64                     goutsum += sir[1];

065.

65                     boutsum += sir[2];

066.

66                 }

067.

67             }

068.

68             stackpointer = radius;

069.

69             for (x =0; x < w; x++) {

070.

70                 r[yi] = dv[rsum];

071.

71                 g[yi] = dv[gsum];

072.

72                 b[yi] = dv[bsum];

073.

73                 rsum -= routsum;

074.

74                 gsum -= goutsum;

075.

75                 bsum -= boutsum;

076.

76                 stackstart = stackpointer - radius + div;

077.

77                 sir = stack[stackstart % div];

078.

78                 routsum -= sir[0];

079.

79                 goutsum -= sir[1];

080.

80                 boutsum -= sir[2];

081.

81                 if (y ==0) {

082.

82                     vmin[x] = Math.min(x + radius +1, wm);

083.

83                 }

084.

84                 p = pix[yw + vmin[x]];

085.

85                 sir[0] = (p &0xff0000) >>16;

086.

86                 sir[1] = (p &0x00ff00) >>8;

087.

87                 sir[2] = (p &0x0000ff);

088.

88                 rinsum += sir[0];

089.

89                 ginsum += sir[1];

090.

90                 binsum += sir[2];

091.

91                 rsum += rinsum;

092.

92                 gsum += ginsum;

093.

93                 bsum += binsum;

094.

94                 stackpointer = (stackpointer +1) % div;

095.

95                 sir = stack[(stackpointer) % div];

096.

96                 routsum += sir[0];

097.

97                 goutsum += sir[1];

098.

98                 boutsum += sir[2];

099.

99                 rinsum -= sir[0];

100.

100                 ginsum -= sir[1];

101.

101                 binsum -= sir[2];

102.

102                 yi++;

103.

103             }

104.

104             yw += w;

105.

105         }

106.

106         for (x =0; x < w; x++) {

107.

107             rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum =0;

108.

108             yp = -radius * w;

109.

109             for (i = -radius; i <= radius; i++) {

110.

110                 yi = Math.max(0, yp) + x;

111.

111                 sir = stack[i + radius];

112.

112                 sir[0] = r[yi];

113.

113                 sir[1] = g[yi];

114.

114                 sir[2] = b[yi];

115.

115                 rbs = r1 - Math.abs(i);

116.

116                 rsum += r[yi] * rbs;

117.

117                 gsum += g[yi] * rbs;

118.

118                 bsum += b[yi] * rbs;

119.

119                 if (i >0) {

120.

120                     rinsum += sir[0];

121.

121                     ginsum += sir[1];

122.

122                     binsum += sir[2];

123.

123                 }else {

124.

124                     routsum += sir[0];

125.

125                     goutsum += sir[1];

126.

126                     boutsum += sir[2];

127.

127                 }

128.

128                 if (i < hm) {

129.

129                     yp += w;

130.

130                 }

131.

131             }

132.

132             yi = x;

133.

133             stackpointer = radius;

134.

134             for (y =0; y < h; y++) {

135.

135                 pix[yi] = (0xff000000 & pix[yi] ) | ( dv[rsum] <<16 ) | ( dv[gsum] <<8 ) | dv[bsum];

136.

136                 rsum -= routsum;

137.

137                 gsum -= goutsum;

138.

138                 bsum -= boutsum;

139.

139                 stackstart = stackpointer - radius + div;

140.

140                 sir = stack[stackstart % div];

141.

141                 routsum -= sir[0];

142.

142                 goutsum -= sir[1];

143.

143                 boutsum -= sir[2];

144.

144                 if (x ==0) {

145.

145                     vmin[y] = Math.min(y + r1, hm) * w;

146.

146                 }

147.

147                 p = x + vmin[y];

148.

148                 sir[0] = r[p];

149.

149                 sir[1] = g[p];

150.

150                 sir[2] = b[p];

151.

151                 rinsum += sir[0];

152.

152                 ginsum += sir[1];

153.

153                 binsum += sir[2];

154.

154                 rsum += rinsum;

155.

155                 gsum += ginsum;

156.

156                 bsum += binsum;

157.

157                 stackpointer = (stackpointer +1) % div;

158.

158                 sir = stack[stackpointer];

159.

159                 routsum += sir[0];

160.

160                 goutsum += sir[1];

161.

161                 boutsum += sir[2];

162.

162                 rinsum -= sir[0];

163.

163                 ginsum -= sir[1];

164.

164                 binsum -= sir[2];

165.

165                 yi += w;

166.

166             }

167.

167         }

168.

168         bitmap.setPixels(pix,0, w,0,0, w, h);

169.

169         return (bitmap);

170.

170     }

171.

171 }