Glide 知識梳理(3) 自定義transform

1、概述

有時候,當咱們去服務器請求圖片資源成功以後,但願先對它進行一些處理,例如縮放、旋轉、蒙灰等,而後再把處理後的圖片展現在控件上,這時候就能夠用上Glide提供的transform()方法,簡單來講,transform()的做用就是改變原始資源在客戶端上最終的展示結果canvas

2、示例

2.1 採用BitmapTransformation進行變換

首先,transform(xxx)接收的參數類型有兩種,一種是BitmapTransformation,另外一種是Transformtion<GifBitmapWrapper>,下面是它們的定義,在平時的使用過程當中,若是咱們的資源爲靜態圖片,而不是Gif或者Media,那麼經過繼承BitmapTransformation來實現本身的變換就能夠了。緩存

//接收BitmapTransformation做爲參數.
    public DrawableRequestBuilder<ModelType> transform(BitmapTransformation... transformations) {
        return bitmapTransform(transformations);
    }
    //接收Transformation做爲參數.
    @Override
    public DrawableRequestBuilder<ModelType> transform(Transformation<GifBitmapWrapper>... transformation) {
        super.transform(transformation);
        return this;
    }
複製代碼

下面,咱們就以一下簡單的例子,來看一下如何使用BitmapTransformation來改變圖片的展現結果。 這裏的變換用到了前面介紹過的setShader相關的知識,能夠參考下面這篇文章:bash

http://www.jianshu.com/p/6ab058329ca8服務器

首先,定義本身的BitmapTransformation實現:app

private class MyBitmapTransformation extends BitmapTransformation {

        public MyBitmapTransformation(Context context) {
            super(context);
        }

        @Override
        protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
            Canvas canvas = new Canvas(toTransform);
            BitmapShader bitmapShader = new BitmapShader(toTransform, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            int min = Math.min(toTransform.getWidth(), toTransform.getHeight());
            int radius = min / 2;
            RadialGradient radialGradient = new RadialGradient(toTransform.getWidth() / 2 , toTransform.getHeight() / 2, radius, Color.TRANSPARENT, Color.WHITE, Shader.TileMode.CLAMP);
            ComposeShader composeShader = new ComposeShader(bitmapShader, radialGradient, PorterDuff.Mode.SRC_OVER);
            Paint paint = new Paint();
            paint.setShader(composeShader);
            canvas.drawRect(0, 0, toTransform.getWidth(), toTransform.getHeight(), paint);
            return toTransform;
        }

        @Override
        public String getId() {
            return "MyBitmapTransformation";
        }
    }
複製代碼

獲得了BitmapTransform以後,經過下面的方式來加載圖片資源,並傳入咱們定義的Transformationide

public void loadTransform(View view) {
        MyBitmapTransformation myBitmapTransformation = new MyBitmapTransformation(this);
        Glide.with(this)
                .load("http://i.imgur.com/DvpvklR.png")
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .transform(myBitmapTransformation)
                .into(mImageView);
    }
複製代碼

最終獲得的結果以下圖所示: ui

2.2 使用多個BitmapTransformation

從上面的定義中,能夠看到transform接收的參數個數是可變,也就是說,咱們能夠傳入多個Transformation進行組合,它們會按順序應用到最終的圖像上。this

3、方法說明

看完上面的應用以後,咱們去源碼中看一下各方法的說明。spa

3.1 Transformation<T>

BitmapTransformation是實現了Transformation<T>接口的抽象類,源碼當中對於Transformation的描述是:code

/**
 * A class for performing an arbitrary transformation on a resource.
 *
 * @param <T> The type of the resource being transformed.
 */
複製代碼

BitmapTransform的參數T就是Bitmap,也就是說它是用來給Bitmap進行變換,Transformation定義了兩個接口:

  • Resource<T> transform(Resource<T> resource, int outWidth, int outHeight) resourceget方法會返回原始資源,它多是從服務器上面下載的圖片,也多是上一個transformation變換後的資源,而返回值就是通過變化後的resource,而outWidth/outHeight就是咱們所要加載到的目標Target的寬高,在上面的例子中,就是ImageView所指定的寬高。
  • String getId() 前面在介紹基礎使用的文章當中,咱們說過最終緩存的資源文件的Cache key會依賴於一些因素,這個getId方法的返回值就是其中的一個因素。

3.2 BitmapTransformation

BitmapTransformation是實現了Transformation的抽象類,它實現了transform(Resource<T> resource, int outWidth, int outHeight)這個方法,並在裏面調用了下面這個方法讓子類去實現,也就是咱們例子中實現的抽象方法,這主要是方便咱們經過BitmapPoolBitmap對象進行復用,同時使用者只用關心須要變換的BitmapBitmapTransformation會負責把它更新回原來的Resource對象中。

protected abstract Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight);
複製代碼

對於這個方法的實現,有幾個須要注意的點:

  • 對於傳入的toTransform Bitmap,不要去回收它或者把它放入到緩存池。若是實現者返回了一個不一樣的Bitmap實例,Glide會負責去回收或者複用toTransform這個Bitmap
  • 不要去回收做爲這個方法返回值的bitmap
  • 若是在這個方法的執行過程當中產生了臨時的Bitmap實例,那麼最好把它放入緩存池,或者回收它。
相關文章
相關標籤/搜索