Case
Glide4.8想要实现加载图片导四个不同的圆角。如下图1
实现思路
在Canvas的四个图层分别绘制四个不同的圆角矩形(RoundRect),然后分别截取(clipRect)左上、右上、右下、左下四个部分,最终在Canvas上组合起来(save->restore)
关键步骤详解
步骤一:原图bitmap关联画笔:
Paint paint =new Paint();
// source 为 transfrom方法中的toTransform Bitmap对象
BitmapShader shader =new BitmapShader(source,Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);
paint.setShader(shader);
paint.setAntiAlias(true);
步骤二:新建画布:
Bitmap outBitmap =this.mBitmapPool.get(source.getWidth(), source.getHeight(),Bitmap.Config.ARGB_8888);
Canvas canvas =new Canvas(outBitmap);
步骤三:分别绘制不同圆角的四个图层,以左上为例:
RectF rectF =new RectF(0,0,canvas.getWidth(),canvas.getHeight());// 与画布同款高的绘制区域
canvas.save();// 图层入栈
canvas.clipRect(0,0,canvas.getWidth() /2,canvas.getHeight() /2);//只取所绘图片的左上1/4部分
canvas.drawRoundRect(rectF, r, r,paint);//绘制圆角矩形
canvas.restore();//图层出栈
以下为BitmapTransformation的完整实现代码:
/**
* author : Conan
* time : 2019-12-19
* desc : 自定义图片四个圆角
*/
public class RoundedCornersTransform extends BitmapTransformation {
private final String ID = getClass().getName();
private Float[] radius = new Float[4];
/**
* 构造方法
*
* @param tl 左上
* @param tr 右上
* @param br 右下
* @param bl 左下
*/
public RoundedCornersTransform(float tl, float tr, float br, float bl) {
this.radius[0] = tl;
this.radius[1] = tr;
this.radius[2] = br;
this.radius[3] = bl;
}
@Override
protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap source, int outWidth, int outHeight) {
Bitmap outBitmap = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(outBitmap);
Paint paint = new Paint();
//关联画笔绘制的原图bitmap
BitmapShader shader = new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
paint.setAntiAlias(true);
RectF rectF = new RectF(0, 0, canvas.getWidth(), canvas.getHeight());
// 左上
float r = radius[0];
canvas.save();
canvas.clipRect(0, 0, canvas.getWidth() / 2, canvas.getHeight() / 2);
canvas.drawRoundRect(rectF, r, r, paint);
canvas.restore();
// 右上
r = radius[1];
canvas.save();
canvas.clipRect(canvas.getWidth() / 2, 0, canvas.getWidth(), canvas.getHeight() / 2);
canvas.drawRoundRect(rectF, r, r, paint);
canvas.restore();
// 右下
r = radius[2];
canvas.save();
canvas.clipRect(canvas.getWidth() / 2, canvas.getHeight() / 2, canvas.getWidth(), canvas.getHeight());
canvas.drawRoundRect(rectF, r, r, paint);
canvas.restore();
// 左下
r = radius[3];
canvas.save();
canvas.clipRect(0, canvas.getHeight() / 2, canvas.getWidth() / 2, canvas.getHeight());
canvas.drawRoundRect(rectF, r, r, paint);
canvas.restore();
return outBitmap;
}
@Override
public void updateDiskCacheKey(MessageDigest messageDigest) {
messageDigest.update(ID.getBytes(CHARSET));
byte[] radiusData = ByteBuffer.allocate(4).putInt(Arrays.hashCode(radius)).array();
messageDigest.update(radiusData);
}
@Override
public boolean equals(Object o) {
if (o instanceof RoundedCornersTransform) {
return Arrays.equals(this.radius, ((RoundedCornersTransform) o).radius);
}
return false;
}
@Override
public int hashCode() {
return Util.hashCode(ID.hashCode(), Arrays.hashCode(radius));
}
}
使用示例
RequestOptions options = new RequestOptions()
.fitCenter() /*处理源图片ScaleType*/
.transform(new RoundedCornersTransform(px, px, px, px));
Glide.with(context).load("url").apply(options).into(imageView);
Canvas基础
Android关于Canvas你所知道的和不知道的一切