不了解Glide的童鞋,可以先前往官网https://github.com/bumptech/glide,或者https://mrfu.me/2016/02/27/Glide_Getting_Started/ 从头开始学习,一步一步了解Glide的各个API的使用。
这里,我只针对近期在做项目的时候遇到要针对原始Bitmap进行转换(变换后)再次显示在ListView 或者Grid上面。
Glide的一般使用只要传入对用的图片或者媒体资源的url地址,Glide就会针对将要显示的控件View(如ImageView)自动压缩变换生成合适尺寸和大小的Bitmap,如果需求发生改变,如:只需要显示图片的某一部分,或者给图片加上特效等等,我们就需要用到Glide的图形转换器:Transformation。你可以用 transformation 去操作 bitmap,从而将一个明亮色彩版本的图片转换成灰暗的版本。不要理解错啦,transformation 不仅限于颜色转换。你可以图片的任意属性:尺寸,范围,颜色,像素位置等等!Glide 已经包含了2个 transformation,即:fitCenter 和 centerCrop。这两个选项都非常有意义,他们在 Glide 中拥有自己的实现。当然,我们这里要实现你自己的 Transformation。
为了实践自定义转换,你将需要创建一个新类,它实现了 Transformation 接口。要实现这个方法还是比较复杂的,你必须要有对 Glide 内部架构方面的洞察力才能做的比较棒。如果你只是想要对图片(不是 Gif 和 video)做常规的 bitmap 转换,我推荐你使用抽象类 BitmapTransformation。它简化了很多的实现,这应该能覆盖 95% 的应用场景啦。来看看 BitmapTransformation 实现实例。我们继承 BitmapTransformation 类。
public class GridBitmapTransformation extends BitmapTransformation {
public BlurTransformation(Context context) {
super( context );
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
//pool: Bitmap缓存池,你可以从中取出你想要复用的Bitmap进行复用,防止重复创建带来的内存消耗。
//toTransform:Glide根据你的View控件压缩后将要现实的Bitmap(也就是经过Glide压缩后的图片)。
//outWidth:将要显示的View的宽,outHeight将要现实的高
//在该方法中你主要针对toTransform 进行变换
return null; // todo
}
@Override
public String getId() {
return null; // todo
}
}
说明:transform 主要用做Bitmap变换的重写,getId 方法描述了这个转换的唯一标识符,Glide 使用该键作为缓存系统的一部分,为了避免意外的问题,你要确保它是唯一的。
下面看下我自己的转换器:
/**
* Description:GridList page image crop converter, generate 1: 1 square 90 degree Bitmap.
* Author: Created by lixby .
*/
public class GridBitmapTransformation extends BitmapTransformation {
private static final String TAG="GridTransformation";
/**Picture horizontal degree*/
private static final int H_DEGREE=360;
/**Picture vertical degree*/
private static final int V_DEGREE=180;
/**Horizontal cropping degree*/
private static final int H_CROPPING_DEGREE=90;
/**vertical cropping degree*/
private static final int V_CROPPING_DEGREE=90;
private static final String TRANSFORMATION_ID="GridBitmapTransformation";
public GridBitmapTransformation(Context context) {
super(context);
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
if (toTransform == null) {
return null;
} else if (toTransform.getWidth() == outWidth && toTransform.getHeight() == outHeight) {
return toTransform;
}
//取出压缩后Bitmap的宽高:注意,压缩后其实只改变了图片的质量(分辨率降低之类),但是图片的尺寸并没有发生变换,之前是什么图,压缩后还是那张图,改变的只是突变质量。
int inWidth=toTransform.getWidth();
int inHeight=toTransform.getHeight();
//根据自己的需求进行Bitmap变化。
int x=((inWidth*(H_DEGREE-H_CROPPING_DEGREE))/H_DEGREE)/2;
int y=((inHeight*(V_DEGREE-V_CROPPING_DEGREE))/V_DEGREE)/2;
int width=inWidth*H_CROPPING_DEGREE/H_DEGREE;
int height=inHeight*V_CROPPING_DEGREE/V_DEGREE;
Bitmap centerBitMap=Bitmap.createBitmap(toTransform,x,y,width,height);
//这里做下主要说明:BitmapPool ,当你在这个方法返回变换后的Bitmap后,Glide会自动帮你将其存入BitmapPool,不需要你去主动添加。而这里是根据你变换后的Bitmap宽高取出对用缓存的Bitmap,可以复用,如果没有就根据你变换要求的Bitmap重新创建一个新的返回就可以了。
Bitmap result = pool.get(centerBitMap.getWidth(), centerBitMap.getHeight(), Bitmap.Config.ARGB_8888);
if(result==null){
result = Bitmap.createBitmap(centerBitMap.getWidth(), centerBitMap.getHeight(), Bitmap.Config.ARGB_8888);
}
//Place the bitmap in the drawing area and draw the picture to be stitched into the specified memory area
Canvas canvas = new Canvas(result);
canvas.drawBitmap(centerBitMap, 0, 0, null);
//Recycle unused BitMap
centerBitMap.recycle();
return result;
}
@Override
public String getId() {
// Return some id that uniquely identifies your transformation.
return TRANSFORMATION_ID;
}
}
上面的案例我写了对用的注释应该不难了理解,强调一点:toTransform 并不需要你去主动回收,GLide会帮助你来回收。
自定义转换器使用:
Glide.with(context).load("url")
.transform(new GridBitmapTransformation(context))
.into(imgItem);
也可以添加多个变化:
Glide.with(context).load("url")
.transform(new GridBitmapTransformation(context),......)
.into(imgItem);
另外:你也可以加入另一个transformations 库,https://github.com/wasabeef/glide-transformations, 里面有很多做好的图形转换,你可以根据自己的需求选择。