Glide之圖片轉(zhuǎn)換成任意形狀

一、圖片轉(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);

```

### 四、效果圖
![glide_transformation.jpg](http://upload-images.jianshu.io/upload_images/226162-dfcc3b19a865ff2d.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

#####demo地址:[https://github.com/zly394/GlideTransform](https://github.com/zly394/GlideTransform)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,007評(píng)論 25 709
  • 轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://www.aiuxian.com/article/p-1982467.html 接下來...
    lucky_yaya閱讀 7,043評(píng)論 3 9
  • 封裝 面向?qū)ο蟮某绦蛟O(shè)計(jì)中,某個(gè)類把所需要的數(shù)據(jù)(也可以說是類的屬性)和對(duì)數(shù)據(jù)的操作(也可以說是類的行為) 全部都...
    勤快的樹懶閱讀 1,019評(píng)論 0 0
  • 身體不舒服本來不打算寫了,可總覺得缺少點(diǎn)東西,依然堅(jiān)持寫完。昨晚就把禮拜天的作業(yè)寫完了,跟兒子商量好了,馬上要期中...
    瑜峰baby閱讀 252評(píng)論 0 1
  • 第一次作文,沒有目的,沒有題材,就當(dāng)隨筆吧,當(dāng)寫完標(biāo)題之后,記憶會(huì)翻滾而來,往事一幕幕涌上心頭,不過想把文章寫好,...
    hootian閱讀 282評(píng)論 0 0

友情鏈接更多精彩內(nèi)容