Glide - 自定義轉換

gxt0102 8年前發布 | 32K 次閱讀 Bitmap Android開發 移動開發 RenderScript

來自: http://mrfu.me/2016/02/28/Glide_Custom_Transformations/

Glide — Custom Transformations

在前面12篇博客中,你已經學到了運用 Glide 標準功能所要求的基礎知識。從這篇博客開始,我們將深入研究一系列進階的話題。這周,我們將仔細看看所謂的轉換。

Glide 系列預覽

  1. 開始!
  2. 加載進階
  3. ListAdapter(ListView, GridView)
  4. 占位符 和 漸現動畫
  5. 圖片重設大小 和 縮放
  6. 顯示 Gif 和 Video
  7. 緩存基礎
  8. 請求優先級
  9. 縮略圖
  10. 回調:SimpleTarget 和 ViewTarget 用于自定義視圖類
  11. 加載圖片到通知欄和應用小部件中
  12. 異常:調試和錯誤處理
  13. 自定義轉換
  14. 用 animate() 自定義動畫
  15. 集成網絡棧
  16. 用 Module 自定義 Glide
  17. Module 實例:接受自簽名證書的 HTTPS
  18. Module 實例:自定義緩存
  19. Module 實例:用自定義尺寸優化加載的圖片
  20. 動態使用 Model Loader
  21. 如何旋轉圖像
  22. 系列綜述

Transformations

在圖片被顯示之前,transformations(轉換) 可以被用于圖像的操作處理。比如,如果你的應用需要顯示一個灰色的圖像,但是我們只能訪問到原始色彩的版本,你可以用 transformation 去操作 bitmap,從而將一個明亮色彩版本的圖片轉換成灰暗的版本。不要理解錯啦,transformation 不僅限于顏色轉換。你可以圖片的任意屬性:尺寸,范圍,顏色,像素位置等等!Glide 已經包含了2個 transformation,我們 之前 已經看了圖像重設大小,即: fitCenter 和 centerCrop 。這兩個選項都非常有意義,他們在 Glide 中擁有自己的實現。當然,我們這篇博客不再介紹他們。

實現你自己的 Transformation

為了實踐自定義轉換,你將需要創建一個新類,它實現了 Transformation 接口 。要實現這個方法還是比較復雜的,你必須要有對 Glide 內部架構方面的洞察力才能做的比較棒。如果你只是想要對圖片(不是 Gif 和 video)做常規的 bitmap 轉換,我們推薦你使用抽象類 BitmapTransformation 。它簡化了很多的實現,這應該能覆蓋 95% 的應用場景啦。

所以,來看看 BitmapTransformation 實現實例。如果你定期閱讀這個博客,你會知道我們喜歡的轉換是 用 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() 里的實現是困惑的,去讀 之前的博客 , 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 。它為 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

使用 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 中實現所有你需要的方式!如果你有問題,在評論中讓我們知道吧。

這篇博客簡述了一個高度可定制的功能,我們會繼續在下一篇博客中這么做。下周,我們會去看看自定義動畫。

</div>

 本文由用戶 gxt0102 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!