您的位置:首页 > 产品设计 > UI/UE

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

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

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

目标效果展示:







第一部分:几个前提

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

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

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

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

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

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

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

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

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

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

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

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

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

设置为maxBlurBitmap,如下图:



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

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

view
sourceprint?

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
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: