Glide图片加载库的使用(二)

Glide图片加载库的使用(二)

--接上篇《Glide图片加载库的使用(一)》--

15.Transformations Bitmap

在显示目标图片之前,我们可以对目标图片的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&lt;Bitmap&gt; transform(Resource&lt;Bitmap&gt; 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 &gt;= 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 &lt;  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 ) &gt;&gt;  1 ;
         divsum *= divsum;
         int dv[] =  new int [ 256 * divsum];
         for (i =  0 ; i &lt;  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 &lt; h; y++) {
             rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum =  0 ;
             for (i = -radius; i &lt;= radius; i++) {
                 p = pix[yi + Math.min(wm, Math.max(i,  0 ))];
                 sir = stack[i + radius];
                 sir[ 0 ] = (p &amp;  0xff0000 ) &gt;&gt;  16 ;
                 sir[ 1 ] = (p &amp;  0x00ff00 ) &gt;&gt;  8 ;
                 sir[ 2 ] = (p &amp;  0x0000ff );
                 rbs = r1 - Math.abs(i);
                 rsum += sir[ 0 ] * rbs;
                 gsum += sir[ 1 ] * rbs;
                 bsum += sir[ 2 ] * rbs;
                 if (i &gt;  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 &lt; 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 &amp;  0xff0000 ) &gt;&gt;  16 ;
                 sir[ 1 ] = (p &amp;  0x00ff00 ) &gt;&gt;  8 ;
                 sir[ 2 ] = (p &amp;  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 &lt; w; x++) {
             rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum =  0 ;
             yp = -radius * w;
             for (i = -radius; i &lt;= 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 &gt;  0 ) {
                     rinsum += sir[ 0 ];
                     ginsum += sir[ 1 ];
                     binsum += sir[ 2 ];
                 }  else {
                     routsum += sir[ 0 ];
                     goutsum += sir[ 1 ];
                     boutsum += sir[ 2 ];
                 }
 
                 if (i &lt; hm) {
                     yp += w;
                 }
             }
             yi = x;
             stackpointer = radius;
             for (y =  0 ; y &lt; h; y++) {
                 // Preserve alpha channel: ( 0xff000000 &amp; pix[yi] )
                 pix[yi] = ( 0xff000000 &amp; pix[yi]) | (dv[rsum] &lt;&lt;  16 ) | (dv[gsum] &lt;&lt;  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);
     }
}

RenderScript处理高斯模糊

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

16.动画处理

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




你可能感兴趣的:(android,图片,Glide,图片加载库)