在前面12篇博客中,你已經學到了運用 Glide 標準功能所要求的基礎知識。從這篇博客開始,我們將深入研究一系列進階的話題。這周,我們將仔細看看所謂的轉換。
**Transformations?**
在圖片被顯示之前,transformations(轉換) 可以被用于圖像的操作處理。比如,如果你的應用需要顯示一個灰色的圖像,但是我們只能訪問到原始色彩的版本,你可以用 transformation 去操作 bitmap,從而將一個明亮色彩版本的圖片轉換成灰暗的版本。不要理解錯啦,transformation 不僅限于顏色轉換。你可以圖片的任意屬性:尺寸,范圍,顏色,像素位置等等!Glide 已經包含了2個 transformation,我們[之前](https://futurestud.io/blog/glide-image-resizing-scaling)已經看了圖像重設大小,即:`fitCenter` 和 `centerCrop`。這兩個選項都非常有意義,他們在 Glide 中擁有自己的實現。當然,我們這篇博客不再介紹他們。
**實現你自己的 Transformation**?
為了實踐自定義轉換,你將需要創建一個新類,它實現了 [Transformation 接口 ](http://bumptech.github.io/glide/javadocs/latest/com/bumptech/glide/load/Transformation.html) 。要實現這個方法還是比較復雜的,你必須要有對 Glide 內部架構方面的洞察力才能做的比較棒。如果你只是想要對圖片(不是 Gif 和 video)做常規的 bitmap 轉換,我們推薦你使用抽象類 [BitmapTransformation](http://bumptech.github.io/glide/javadocs/latest/com/bumptech/glide/load/resource/bitmap/BitmapTransformation.html)。它簡化了很多的實現,這應該能覆蓋 95% 的應用場景啦。
所以,來看看 `BitmapTransformation` 實現實例。如果你定期閱讀這個博客,你會知道我們喜歡的轉換是 [用 Renderscript 模糊圖像](https://futurestud.io/blog/how-to-blur-images-efficiently-with-androids-renderscript)。我們可以將之前的所有代碼重用到 Glide 的轉換中。因為我們繼承 `BitmapTransformation` 類,我們用這樣的框架:
~~~
public class BlurTransformation extends BitmapTransformation {
public BlurTransformation(Context context) {
super( context );
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return null; // todo
}
@Override
public String getId() {
return null; // todo
}
}
~~~
現在我們將之前博客中用 Renderscript 來模糊圖像的代碼放到我們這里來:
~~~
public class BlurTransformation extends BitmapTransformation {
private RenderScript rs;
public BlurTransformation(Context context) {
super( context );
rs = RenderScript.create( context );
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
Bitmap blurredBitmap = toTransform.copy( Bitmap.Config.ARGB_8888, true );
// Allocate memory for Renderscript to work with
Allocation input = Allocation.createFromBitmap(
rs,
blurredBitmap,
Allocation.MipmapControl.MIPMAP_FULL,
Allocation.USAGE_SHARED
);
Allocation output = Allocation.createTyped(rs, input.getType());
// Load up an instance of the specific script that we want to use.
ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
script.setInput(input);
// Set the blur radius
script.setRadius(10);
// Start the ScriptIntrinisicBlur
script.forEach(output);
// Copy the output to the blurred bitmap
output.copyTo(blurredBitmap);
toTransform.recycle();
return blurredBitmap;
}
@Override
public String getId() {
return "blur";
}
}
~~~
再說一次,如果你對于代碼塊 `transform()` 里的實現是困惑的,去讀[之前的博客](https://futurestud.io/blog/how-to-blur-images-efficiently-with-androids-renderscript),`getId()` 方法描述了這個轉換的唯一標識符。Glide 使用該鍵作為緩存系統的一部分,為了避免意外的問題,你要確保它是唯一的。
下一節,我們要學習如何應用我們之前創建的轉換。
`單個轉換的應用`?
Glide 有兩種方式去使用轉換。首先是傳一個的你的類的實例作為參數給 `.transform()`。你這里你可以使用任何轉換,無論它是否是用于圖像還是 Gif。其他選擇是使用 `.bitmapTransform()`,它只能用于 bitmap 的轉換。因為我們上面的實現是為 bitmap 設計的,這兩者我們都可以用:
~~~
Glide
.with( context )
.load( eatFoodyImages[0] )
.transform( new BlurTransformation( context ) )
//.bitmapTransform( new BlurTransformation( context ) ) // this would work too!
.into( imageView1 );
~~~
**運用多種轉換?**
通常,Glide 的流式接口允許方法以鏈式的形式。然而對于轉換卻并不在這種場景下。確保你只調用了一次 `.transform()` 或 `.bitmapTransform()`,否則,之前的配置就會被覆蓋掉的!然而,你還是可以運用多種轉換的,通過傳遞多個轉換對象作為參數傳給 `.transform()` 或 `.bitmapTransform()`。
~~~
Glide
.with( context )
.load( eatFoodyImages[1] )
.transform( new GreyscaleTransformation( context ), new BlurTransformation( context ) )
.into( imageView2 );
~~~
這個代碼片段中,我們把一個圖像設置了灰度,然后做了模糊。Glide 為你自動執行了這兩個轉換。Awesome!
提示:當你用了轉換后你就不能使用 `.centerCrop()` 或 `.fitCenter() `了。
**Glide 轉換集合**?
如果你已經有了做什么樣轉換的想法,你可以會想要用到你的 App 里,花點時間看下這個庫:[glide-transformations](https://github.com/wasabeef/glide-transformations)。它為 Glide 轉換提供了多種多樣的實現。非常值得去看一下,說不定你的想法已經在它那里實現了。
這個庫有兩個不同的版本。擴展版本包含了更多的轉換,它是通過設備的 GPU 來計算處理的。這個版本需要有額外的依賴,所以這兩個版本的設置有一點不同。你應該看看所擁有的轉換方法的列表,再去決定你需要使用哪個版本。
**Glide 轉換設置**?
設置起來很簡單,對于基礎版本你只需要在你當前的 `build.gradle` 中添加一行代碼就可以了。
~~~
dependencies {
compile 'jp.wasabeef:glide-transformations:1.2.1'
}
~~~
如果你想要使用 GPU 轉換:
~~~
repositories {
jcenter()
mavenCentral()
}
dependencies {
compile 'jp.wasabeef:glide-transformations:1.2.1'
compile 'jp.co.cyberagent.android.gpuimage:gpuimage-library:1.3.0'
}
~~~
如果你想使用 `BlurTransformation`,你需要多一個步驟。如果你還沒做的話,那就添加下面這些代碼到你的 `build.gradle` 中。
~~~
android {
...
defaultConfig {
...
renderscriptTargetApi 23
renderscriptSupportModeEnabled true
}
}
~~~
如果你想要知道更多關于這個步驟的東西,去看看我們的這篇博客: [blog post about Renderscript](https://futurestud.io/blog/how-to-use-the-renderscript-support-library-with-gradle-based-android-projects)。
**使用 Glide 的轉換**?
當你將 `build.gradle `文件在 Android Studio 同步了之后,你可以去使用這個轉換集合了。使用模式和你自己定義轉換的方式相同。假設我們想要做用這個集合的模糊轉換去模糊一張圖片:
~~~
Glide
.with( context )
.load( eatFoodyImages[2] )
.bitmapTransform( new jp.wasabeef.glide.transformations.BlurTransformation( context, 25, 2 ) )
.into( imageView3 );
~~~
就像我們上面所以用的,你也可以使用一連串的轉換。`.bitmapTransform()` 方法都接受一個或多個轉換。
**Outlook?**
這篇博客中,你學到了 Glide 非常有用的工具:轉換!你已經學會如何去實現并應用預定義的以及自定義的轉換。我們喜歡這能在你的 App 中實現所有你需要的方式!如果你有問題,在評論中讓我們知道吧。
這篇博客簡述了一個高度可定制的
- 前言
- 一開始
- 二加載進階
- 三ListAdapter(ListView, GridView)
- 四占位符 和 漸現動畫
- 五圖片重設大小 和 縮放
- 六顯示 Gif 和 Video
- 七緩存基礎
- 八請求優先級
- 九縮略圖
- 十回調:SimpleTarget 和 ViewTarget 用于自定義視圖類
- 十一加載圖片到通知欄和應用小部件中
- 十二異常:調試和錯誤處理
- 十三自定義轉換
- 十四用 animate() 自定義動畫
- 十五集成網絡棧
- 十六用 Module 自定義
- 十七Module 實例:接受自簽名證書的 HTTPS
- 十八Module 實例:自定義緩存
- 十九Module 實例:用自定義尺寸優化加載的圖片
- 二十動態使用 Model Loader
- 二十一如何旋轉圖像
- 二十二系列綜述