一、概述
有時候,當我們去伺服器請求圖片資源成功之後,希望先對它進行一些處理,例如縮放、旋轉、蒙灰等,然後再把處理後的圖片展示在控制元件上,這時候就可以用上Glide
提供的transform()
方法,簡單來說,transform()
的作用就是改變原始資源在客戶端上最終的展現結果。
二、示例
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
相關的知識,可以參考下面這篇文章:
首先,定義自己的BitmapTransformation
實現:
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
之後,通過下面的方式來載入圖片資源,並傳入我們定義的Transformation
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);
}
複製程式碼
最終得到的結果如下圖所示:
2.2 使用多個BitmapTransformation
從上面的定義中,可以看到transform
接收的引數個數是可變,也就是說,我們可以傳入多個Transformation
進行組合,它們會按順序應用到最終的影像上。
三、方法說明
看完上面的應用之後,我們去原始碼中看一下各方法的說明。
3.1 Transformation<T>
BitmapTransformation
是實現了Transformation<T>
介面的抽象類,原始碼當中對於Transformation
的描述是:
/**
* 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)
resource
的get
方法會返回原始資源,它可能是從伺服器上面下載的圖片,也可能是上一個transformation
變換後的資源,而返回值就是經過變化後的resource
,而outWidth/outHeight
就是我們所要載入到的目標Target
的寬高,在上面的例子中,就是ImageView
所指定的寬高。String getId()
前面在介紹基礎使用的文章當中,我們說過最終快取的資原始檔的Cache key
會依賴於一些因素,這個getId
方法的返回值就是其中的一個因素。
3.2 BitmapTransformation
BitmapTransformation
是實現了Transformation
的抽象類,它實現了transform(Resource<T> resource, int outWidth, int outHeight)
這個方法,並在裡面呼叫了下面這個方法讓子類去實現,也就是我們例子中實現的抽象方法,這主要是方便我們通過BitmapPool
對Bitmap
物件進行復用,同時使用者只用關心需要變換的Bitmap
,BitmapTransformation
會負責把它更新回原來的Resource
物件中。
protected abstract Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight);
複製程式碼
對於這個方法的實現,有幾個需要注意的點:
- 對於傳入的
toTransform Bitmap
,不要去回收它或者把它放入到快取池。如果實現者返回了一個不同的Bitmap
例項,Glide
會負責去回收或者複用toTransform
這個Bitmap
。 - 不要去回收作為這個方法返回值的
bitmap
。 - 如果在這個方法的執行過程中產生了臨時的
Bitmap
例項,那麼最好把它放入快取池,或者回收它。