一、圖片轉(zhuǎn)換形狀原理
設(shè)置Paint的Xfermode(相交模式),來設(shè)置兩張圖片相交時(shí)的顯示方式
PorterDuffXfermode是Xfermode的子類,是一個(gè)很強(qiáng)大的轉(zhuǎn)換模式,共有16種模式,如下圖所示,其中黃色圓圖為下層圖片,藍(lán)色方圖為上層圖片。具體可以查看Android ApiDemos,Android Studio導(dǎo)入Samples方法

proter_duff_mode.jpg
利用這種圖片相交轉(zhuǎn)換方式,可以實(shí)現(xiàn)任意形狀圖片的轉(zhuǎn)換
二、繼承BitmapTransformation自定義圖片變換類
BitmapTransformation類是一個(gè)抽象類,實(shí)現(xiàn)了Transformation<T>接口,其中有兩個(gè)方法需要重寫。
// Transformation<T>接口中的方法,用于獲取緩存的唯一標(biāo)識(shí)符
String getId();
// BitmapTransformation抽象類的抽象方法,用于完成圖片的轉(zhuǎn)換
protected abstract Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight);
CustomShapeTransformation.java
public class CustomShapeTransformation extends BitmapTransformation {
private Paint mPaint; // 畫筆
private Context mContext;
private int mShapeRes; // 形狀的drawable資源
public CustomShapeTransformation(Context context, int shapeRes) {
super(context);
mContext = context;
mShapeRes = shapeRes;
// 實(shí)例化Paint對(duì)象,并設(shè)置Xfermode為SRC_IN
mPaint = new Paint();
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
}
@Override
// 復(fù)寫該方法,完成圖片的轉(zhuǎn)換
public Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
// 獲取到形狀資源的Drawable對(duì)象
Drawable shape = ContextCompat.getDrawable(mContext, mShapeRes);
float shapeWidth = shape.getMinimumWidth(); // 形狀的寬
float shapeHeight = shape.getMinimumHeight(); // 形狀的高
int width = toTransform.getWidth(); // 圖片的寬
int height = toTransform.getHeight(); // 圖片的高
if (width > height) {
// 如果圖片的寬大于高,則以高為基準(zhǔn),以形狀的寬高比重新設(shè)置寬度
width = (int) (height * (shapeWidth / shapeHeight));
} else {
// 如果圖片的寬小于等于高,則以寬為基準(zhǔn),以形狀的寬高比重新設(shè)置高度度
height = (int) (width * (shapeHeight / shapeWidth));
}
// 居中裁剪圖片,調(diào)用Glide庫(kù)中TransformationUtils類的centerCrop()方法完成裁剪,保證圖片居中且填滿
final Bitmap toReuse = pool.get(width, height, toTransform.getConfig() != null
? toTransform.getConfig() : Bitmap.Config.ARGB_8888);
Bitmap transformed = TransformationUtils.centerCrop(toReuse, toTransform, width, height);
if (toReuse != null && toReuse != transformed && !pool.put(toReuse)) {
toReuse.recycle();
}
// 根據(jù)算出的寬高新建Bitmap對(duì)象并設(shè)置到畫布上
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
// 設(shè)置形狀的大小與圖片的大小一致
shape.setBounds(0, 0, width, height);
// 將圖片畫到畫布上
shape.draw(canvas);
// 將裁剪后的圖片畫得畫布上
canvas.drawBitmap(transformed, 0, 0, mPaint);
return bitmap;
}
@Override
public String getId() {
// 用于緩存的唯一標(biāo)識(shí)符
return "CustomShapeTransformation" + mShapeRes;
}
}
三、調(diào)用轉(zhuǎn)換
Glide.with(this).load(url).transform(new CustomShapeTransformation).into(imageView);
// 或
Glide.with(this).load(url).bitmapTransform(new CustomShapeTransformation).into(imageView);
```
### 四、效果圖

#####demo地址:[https://github.com/zly394/GlideTransform](https://github.com/zly394/GlideTransform)