Glide — 自定義變換
原文:Custom Transformation
作者:Norman Peitek
翻譯:Dexter0218
前面的12篇文章中汹桦,你已經(jīng)學(xué)會(huì)了所有的基礎(chǔ)請(qǐng)求去實(shí)現(xiàn)Glide的標(biāo)準(zhǔn)功能溃列。從這篇文章開始,我們將要深入研究一些高級(jí)話題膝晾。這篇文章進(jìn)一步研究變換(Transformations)赏迟。
Glide 系列概覽
- 入門簡(jiǎn)介
- 高級(jí)加載
- 適配器(ListView, GridView)
- 占位圖& 淡入淡出動(dòng)畫
- 圖片大小 & 縮放
- 播放GIF & 視頻
- 緩存基礎(chǔ)
- 請(qǐng)求優(yōu)先級(jí)
- 縮略圖
- 回調(diào):定制view中使用SimpleTarget和ViewTarget
- 通知欄和桌面小控件的圖片加載
- 異常: 調(diào)試和報(bào)錯(cuò)處理
- 自定義變換
- 用animate()定制動(dòng)畫
- 整合網(wǎng)絡(luò)協(xié)議棧
- 用Modules定制Glide
- Glide Module 案例: 接受自簽名HTTPS證書
- Glide Module 案例: 自定義緩存
- Glide Module 案例: 通過加載自定義大小圖片優(yōu)化
- 動(dòng)態(tài)使用 Model Loaders
- 如何旋轉(zhuǎn)圖片
- 系列綜述
變換
在圖片顯示出之前可以對(duì)圖片進(jìn)行變換處理约素。例如洽故,如果你的app需要顯示一張灰度圖贝攒,但只能獲取到一個(gè)原始全色彩的版本,你可以使用一個(gè)變換去將圖片從有明艷色彩的版本轉(zhuǎn)換成慘淡的黑白版时甚。不要誤會(huì)我們隘弊,變換不僅限于顏色。你可以改變圖片的很多屬性:大小撞秋、邊框长捧、色彩嚣鄙、像素點(diǎn)吻贿,等等!在之前介紹用Glide調(diào)整圖片大小時(shí)哑子,已經(jīng)介紹了自帶的兩個(gè)變換fitCenter
和 centerCrop
舅列。這兩個(gè)方案都有一個(gè)顯著的特征肌割,他們有他們自己的Glide轉(zhuǎn)換方法,所以帐要,這篇文章不再介紹了把敞。
實(shí)現(xiàn)你自己的變換
為了實(shí)現(xiàn)你自己自定義的變換,你需要?jiǎng)?chuàng)建一個(gè)新的類去實(shí)現(xiàn)變換接口榨惠。這個(gè)方法需要實(shí)現(xiàn)的內(nèi)容還是相當(dāng)復(fù)雜的奋早,你需要深入探索Glide的內(nèi)部結(jié)構(gòu)才能讓其工作好。如果你只是想要常規(guī)的圖片(不包括Gif和視頻)變換赠橙,我們建議只要處理抽象的BitmapTransformation
類耽装。它簡(jiǎn)化了相當(dāng)多的實(shí)現(xiàn),能覆蓋95%的使用范圍期揪。
所以掉奄,讓我們先看一下BitmapTransformation
實(shí)現(xiàn)的一個(gè)例子。如果你有規(guī)律地看我們的文章凤薛,你知道我們最喜歡的變換是用Renderscript
去模糊圖片姓建。我們可以用之前用過的代碼去實(shí)現(xiàn)一個(gè)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
}
}
現(xiàn)在缤苫,我們用前面文章的代碼速兔,借助Renderscript
來實(shí)現(xiàn)圖片的模糊處理。
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";
}
}
再次提醒活玲,如果你對(duì)transform()
里的代碼困惑憨栽,建議看看之前的文章。getId()
方法為這個(gè)變換描述了一個(gè)獨(dú)有的識(shí)別翼虫。Glide使用那個(gè)關(guān)鍵字作為緩存系統(tǒng)的一部分屑柔。防止出現(xiàn)異常問題,確保其唯一珍剑。
下一節(jié)掸宛,我們要學(xué)習(xí)如何應(yīng)用我們創(chuàng)建的變換方法。
應(yīng)用一個(gè)簡(jiǎn)單的變換
Glide has two ways of applying a transformation. The first is to pass an instance of your class as a parameter to .transform(). You can apply any transformation there, no matter if it's for an image or Gif. The other option is to use .bitmapTransform(), which only accepts transformations for bitmaps. Since our implementation above is designed for bitmaps, we could use either one:
Glide有兩個(gè)不同的方式進(jìn)行變換招拙。第一個(gè)是傳遞一個(gè)你的類的實(shí)例作為.transform()
的參數(shù)唧瘾。不管是圖片還是gif,都可以進(jìn)行變換别凤。另一個(gè)則是使用.bitmapTransform()
饰序,它只接受bitmap的變換。由于我們的實(shí)現(xiàn)都是基于bitmap规哪,我們可以使用第一個(gè):
Glide
.with( context )
.load( eatFoodyImages[0] )
.transform( new BlurTransformation( context ) )
//.bitmapTransform( new BlurTransformation( context ) ) // this would work too!
.into( imageView1 );
這足夠讓Glide從網(wǎng)絡(luò)下載的圖片自動(dòng)實(shí)現(xiàn)模糊算法求豫。非常有用!
實(shí)現(xiàn)多重變換
通常,Glide的流接口(fluent interface)允許方法被連接在一起蝠嘉,然而變換并不是這樣的最疆。確保你只調(diào)用.transform()
或者.bitmapTransform()
一次,不然蚤告,之前的設(shè)置將會(huì)被覆蓋努酸!然而,你可以通過傳遞多個(gè)轉(zhuǎn)換對(duì)象當(dāng)作參數(shù)到.transform()
(或者.bitmapTransform()
)中來進(jìn)行多重變換:
Glide
.with( context )
.load( eatFoodyImages[1] )
.transform( new GreyscaleTransformation( context ), new BlurTransformation( context ) )
.into( imageView2 );
在這段代碼中杜恰,我們先對(duì)圖片進(jìn)行了灰度變換获诈,然后模糊處理。Glide會(huì)為你自動(dòng)進(jìn)行兩個(gè)轉(zhuǎn)換心褐。牛逼吧烙荷!
提示:當(dāng)你使用變換的時(shí)候,你不能使用.centerCrop()
或者.fitCenter()
檬寂。
Glide的變換集合
如果你已經(jīng)對(duì)你的app里要用什么變換有了想法终抽,在花點(diǎn)時(shí)間看看下面的庫(kù)吧:Glide-transformations。它提供了許多變換的集合桶至。值得去看一下你的idea是否已經(jīng)被實(shí)現(xiàn)了昼伴。
這個(gè)庫(kù)有2個(gè)不同版本。擴(kuò)展庫(kù)包括更多的變換镣屹,并且是用手機(jī)的GPU進(jìn)行計(jì)算圃郊。需要一個(gè)額外的依賴,所以這兩個(gè)版本的設(shè)置還有點(diǎn)不一樣女蜈。你應(yīng)當(dāng)看看支持的變換的列表持舆,再?zèng)Q定你需要用哪個(gè)版本。
Glide變換的設(shè)置
設(shè)置是很簡(jiǎn)單的伪窖!對(duì)于基本版逸寓,你可以在你的build.gradle里加一行:
dependencies {
compile 'jp.wasabeef:glide-transformations:2.0.0'
}
如果你想要使用GPU變換:
repositories {
jcenter()
mavenCentral()
}
dependencies {
compile 'jp.wasabeef:glide-transformations:2.0.0'
compile 'jp.co.cyberagent.android.gpuimage:gpuimage-library:1.3.0'
}
Glide變換的使用
在你同步了Android Studio的builde.gradle文件后,你已經(jīng)可以進(jìn)行使用變換集合了覆山。使用方式與使用自定義變換一樣竹伸。假如我們要用glide變換集合去模糊圖片:
Glide
.with( context )
.load( eatFoodyImages[2] )
.bitmapTransform( new jp.wasabeef.glide.transformations.BlurTransformation( context, 25 ) )
.into( imageView3 );
你也可以像上面一樣應(yīng)用一組變換。一個(gè)單獨(dú)的變換或者一組變換簇宽,.bitmapTransform()
都可以接受勋篓!
展望
這邊文章中,你已經(jīng)學(xué)會(huì)了Glide的一個(gè)非常有用的工具:變換魏割。你已經(jīng)知道如何實(shí)現(xiàn)并應(yīng)用預(yù)定義的變換譬嚣,我們希望這提供給你應(yīng)用到app里所有需要的幫助!如果你有問題钞它,在評(píng)論區(qū)提出拜银!
這篇文件講解了一個(gè)非常定制化的特征殊鞭,后面的文章將介紹另一個(gè):自定義動(dòng)畫。