Glide图片加载库的使用(二)
--接上篇《Glide图片加载库的使用(一)》--
在显示目标图片之前,我们可以对目标图片的Bitmap进行相应的处理,例如::圆角图片,圆形图片,高斯模糊,旋转,灰度等等.
只需要实现Transformation接口即可,该接口的transform方法会返回显示图片前的Bitmap对象,在该方法中对
Bitmap的任何处理,都会影响到最终的显示结果.
当然,如果你只是想要对图片做常规的 bitmap 转换,你可以继承抽象类BitmapTransformation,它简化了Transformation接口的实现,这应该能覆盖大部分的应用场景了。
使用的时候,通过transform(Transformation… transformations)来设置.例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public
class
TestGlideActivity
extends
Activity {
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
Glide.with(
this
).
load(R.drawable.test).
asBitmap().
transform(
new
BlurTransformation(
this
)).
//高斯模糊处理
into(targetView);
}
}
|
下面贴出常用的几个Bitmap的转换处理的代码,在github上也有glide-transformations-master库.
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
|
public
class
CropCircleTransformation
implements
Transformation<Bitmap> {
private
BitmapPool mBitmapPool;
public
CropCircleTransformation(Context context) {
this
(Glide.get(context).getBitmapPool());
}
public
CropCircleTransformation(BitmapPool pool) {
this
.mBitmapPool = pool;
}
@Override
public
Resource<Bitmap> transform(Resource<Bitmap> resource,
int
outWidth,
int
outHeight) {
Bitmap source = resource.get();
int
size = Math.min(source.getWidth(), source.getHeight());
int
width = (source.getWidth() - size) /
2
;
int
height = (source.getHeight() - size) /
2
;
Bitmap bitmap = mBitmapPool.get(size, size, Bitmap.Config.ARGB_8888);
if
(bitmap ==
null
) {
bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
}
Canvas canvas =
new
Canvas(bitmap);
Paint paint =
new
Paint();
BitmapShader shader =
new
BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
if
(width !=
0
|| height !=
0
) {
// source isn't square, move viewport to center
Matrix matrix =
new
Matrix();
matrix.setTranslate(-width, -height);
shader.setLocalMatrix(matrix);
}
paint.setShader(shader);
paint.setAntiAlias(
true
);
float
r = size / 2f;
canvas.drawCircle(r, r, r, paint);
return
BitmapResource.obtain(bitmap, mBitmapPool);
}
@Override
public
String getId() {
return
"CropCircleTransformation()"
;
}
}
|
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
|
public
class
RoundedCornersTransformation
implements
Transformation<Bitmap> {
private
BitmapPool mBitmapPool;
private
int
radius;
private
int
margin;
public
RoundedCornersTransformation(Context context,
int
radius,
int
margin) {
this
(Glide.get(context).getBitmapPool(), radius, margin);
}
public
RoundedCornersTransformation(BitmapPool pool,
int
radius,
int
margin) {
mBitmapPool = pool;
this
.radius = radius;
this
.margin = margin;
}
@Override
public
Resource<Bitmap> transform(Resource<Bitmap> resource,
int
outWidth,
int
outHeight) {
Bitmap source = resource.get();
int
width = source.getWidth();
int
height = source.getHeight();
Bitmap bitmap = mBitmapPool.get(width, height, Bitmap.Config.ARGB_8888);
if
(bitmap ==
null
) {
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
}
Canvas canvas =
new
Canvas(bitmap);
Paint paint =
new
Paint();
paint.setAntiAlias(
true
);
paint.setShader(
new
BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawRoundRect(
new
RectF(margin, margin, width - margin, height - margin), radius, radius,
paint);
return
BitmapResource.obtain(bitmap, mBitmapPool);
}
@Override
public
String getId() {
return
"RoundedTransformation(radius="
+ radius +
", margin="
+ margin +
")"
;
}
}
|
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
|
public
class
GrayscaleTransformation
implements
Transformation<Bitmap> {
private
BitmapPool mBitmapPool;
public
GrayscaleTransformation(Context context) {
this
(Glide.get(context).getBitmapPool());
}
public
GrayscaleTransformation(BitmapPool pool) {
mBitmapPool = pool;
}
@Override
public
Resource<Bitmap> transform(Resource<Bitmap> resource,
int
outWidth,
int
outHeight) {
Bitmap source = resource.get();
int
width = source.getWidth();
int
height = source.getHeight();
Bitmap.Config config =
source.getConfig() !=
null
? source.getConfig() : Bitmap.Config.ARGB_8888;
Bitmap bitmap = mBitmapPool.get(width, height, config);
if
(bitmap ==
null
) {
bitmap = Bitmap.createBitmap(width, height, config);
}
Canvas canvas =
new
Canvas(bitmap);
ColorMatrix saturation =
new
ColorMatrix();
saturation.setSaturation(0f);
Paint paint =
new
Paint();
paint.setColorFilter(
new
ColorMatrixColorFilter(saturation));
canvas.drawBitmap(source,
0
,
0
, paint);
return
BitmapResource.obtain(bitmap, mBitmapPool);
}
@Override
public
String getId() {
return
"GrayscaleTransformation()"
;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public
class
RotateTransformation
extends
BitmapTransformation {
private
float
rotateRotationAngle = 0f;
public
RotateTransformation(Context context,
float
rotateRotationAngle) {
super
(context);
this
.rotateRotationAngle = rotateRotationAngle;
}
@Override
protected
Bitmap transform(BitmapPool pool, Bitmap toTransform,
int
outWidth,
int
outHeight) {
Matrix matrix =
new
Matrix();
matrix.postRotate(rotateRotationAngle);
return
Bitmap.createBitmap(toTransform,
0
,
0
, toTransform.getWidth(), toTransform.getHeight(), matrix,
true
);
}
@Override
public
String getId() {
return
"rotate"
+ rotateRotationAngle;
}
}
|
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
|
public
class
BlurTransformation
implements
Transformation<Bitmap> {
private
static
int
MAX_RADIUS =
25
;
private
static
int
DEFAULT_DOWN_SAMPLING =
1
;
private
Context mContext;
private
BitmapPool mBitmapPool;
private
int
mRadius;
private
int
mSampling;
public
BlurTransformation(Context context) {
this
(context, Glide.get(context).getBitmapPool(), MAX_RADIUS, DEFAULT_DOWN_SAMPLING);
}
public
BlurTransformation(Context context, BitmapPool pool) {
this
(context, pool, MAX_RADIUS, DEFAULT_DOWN_SAMPLING);
}
public
BlurTransformation(Context context, BitmapPool pool,
int
radius) {
this
(context, pool, radius, DEFAULT_DOWN_SAMPLING);
}
public
BlurTransformation(Context context,
int
radius) {
this
(context, Glide.get(context).getBitmapPool(), radius, DEFAULT_DOWN_SAMPLING);
}
public
BlurTransformation(Context context, BitmapPool pool,
int
radius,
int
sampling) {
mContext = context;
mBitmapPool = pool;
mRadius = radius;
mSampling = sampling;
}
public
BlurTransformation(Context context,
int
radius,
int
sampling) {
mContext = context;
mBitmapPool = Glide.get(context).getBitmapPool();
mRadius = radius;
mSampling = sampling;
}
@Override
public
Resource<Bitmap> transform(Resource<Bitmap> resource,
int
outWidth,
int
outHeight) {
Bitmap source = resource.get();
int
width = source.getWidth();
int
height = source.getHeight();
int
scaledWidth = width / mSampling;
int
scaledHeight = height / mSampling;
Bitmap bitmap = mBitmapPool.get(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);
if
(bitmap ==
null
) {
bitmap = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);
}
Canvas canvas =
new
Canvas(bitmap);
canvas.scale(
1
/ (
float
) mSampling,
1
/ (
float
) mSampling);
Paint paint =
new
Paint();
paint.setFlags(Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(source,
0
,
0
, paint);
if
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
try
{
bitmap = RSBlur.blur(mContext, bitmap, mRadius);
}
catch
(RSRuntimeException e) {
bitmap = FastBlur.blur(bitmap, mRadius,
true
);
}
}
else
{
bitmap = FastBlur.blur(bitmap, mRadius,
true
);
}
return
BitmapResource.obtain(bitmap, mBitmapPool);
}
@Override
public
String getId() {
return
"BlurTransformation(radius="
+ mRadius +
", sampling="
+ mSampling +
")"
;
}
}
|
网上提供的FastBlur,可兼容低版本的高斯模糊处理
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
202
203
204
205
206
207
208
209
|
public
class
FastBlur {
public
static
Bitmap blur(Bitmap sentBitmap,
int
radius,
boolean
canReuseInBitmap) {
Bitmap bitmap;
if
(canReuseInBitmap) {
bitmap = sentBitmap;
}
else
{
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
dv[] =
new
int
[
256
* divsum];
for
(i =
0
; i <
256
* divsum; 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++) {
// Preserve alpha channel: ( 0xff000000 & pix[yi] )
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);
}
}
|
android4.3之后可使用,需要在build.gradle中配置:
defaultConfig {
//BlurTransformation
renderscriptTargetApi 23
renderscriptSupportModeEnabled true
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public
class
RSBlur {
@TargetApi
(Build.VERSION_CODES.JELLY_BEAN_MR2)
public
static
Bitmap blur(Context context, Bitmap blurredBitmap,
int
radius)
throws
RSRuntimeException {
try
{
RenderScript rs = RenderScript.create(context);
Allocation input = Allocation.createFromBitmap(rs, blurredBitmap, Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_SCRIPT);
Allocation output = Allocation.createTyped(rs, input.getType());
ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
blur.setInput(input);
blur.setRadius(radius);
blur.forEach(output);
output.copyTo(blurredBitmap);
rs.destroy();
}
catch
(RSRuntimeException e) {
blurredBitmap = FastBlur.blur(blurredBitmap, radius,
true
);
}
return
blurredBitmap;
}
}
|
通过animate()方法可以设置xml文件定义的4种补间动画(alpha、scale、translate、rotate)
例如:
res\anim\left_in.xml
1
2
3
4
5
6
7
8
9
10
11
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
set
xmlns:android
=
"http://schemas.android.com/apk/res/android"
>
<
translate
android:duration
=
"@android:integer/config_mediumAnimTime"
android:fromXDelta
=
"-50%p"
android:toXDelta
=
"0"
/>
<
alpha
android:duration
=
"@android:integer/config_mediumAnimTime"
android:fromAlpha
=
"0.0"
android:toAlpha
=
"1.0"
/>
</
set
>
|
使用方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public
class
TestGlideActivity
extends
Activity {
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
Glide.with(
this
).
load(R.drawable.test).
asBitmap().
animate(R.anim.left_in).
//加载xml文件定义的动画
into(targetView);
}
}
|
处理此外,还可以通过animate指定属性动画:
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
|
public
class
TestGlideActivity
extends
Activity {
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ImageView targetView = (ImageView) findViewById(R.id.iv_target);
ViewPropertyAnimation.Animator animationObject =
new
ViewPropertyAnimation.Animator() {
@Override
public
void
animate(View view) {
//设置属性动画
ObjectAnimator moveIn = ObjectAnimator.ofFloat(view,
"translationX"
, -500f, 0f);
ObjectAnimator rotate = ObjectAnimator.ofFloat(view,
"rotation"
, 0f, 360f);
ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(view,
"alpha"
, 1f, 0f, 1f);
ObjectAnimator moveTop = ObjectAnimator.ofFloat(view,
"translationY"
, 0f, -
2000
, 0f);
AnimatorSet animSet =
new
AnimatorSet();
//先左进,然后旋转伴随淡入效果,最后移动向上
animSet.play(rotate).with(fadeInOut).after(moveIn).before(moveTop);
animSet.setDuration(
5000
);
animSet.start();
}
};
Glide.with(
this
).
load(R.drawable.test).
asBitmap().
animate(animationObject).
//加载属性动画
into(targetView);
}
}
|