我就不廢話了,直接貼代碼:
val target = object : SimpleTarget<Bitmap>(width,height) { //①
override fun onResourceReady(resource: Bitmap, glideAnimation: GlideAnimation<in Bitmap>) {
src = resource
mMatrix.reset()
invalidate()
}
}
Glide.with(context)
.load(imagePath)
.asBitmap()/*.override(width ,height)*/
.into(target) //②
這段代碼想要實現的邏輯很簡單
①處我們構建了一個供 Glide 的 into 方法使用的 SimpleTarget 對象。這里注意提供給 SimpleTarget 構造函數的兩個參數,
Glide 會按照我們提供的兩個參數值對待加載圖片的尺寸進行調整,使加載出的圖片尺寸剛好等于我們設定的值。注意這里給 SimpleTarget 的構造函數設定參數值的方式與②處我們對 Glide 調用 override 方法是等價的,都是手動設置加載結果尺寸的有效方法,SimpleTarget 的 onResourceReady 方法中的邏輯不必細究,這段代碼是寫在一個自定義 View 里的,其邏輯就是按確定尺寸把圖片資源加載出來。
嗯,看起來萬事俱備,如果你以為這就可以按預想尺寸加載出圖片那就太天真了,我寫到這一步然后運行程序的時候發現加載出的 Bitmap 對象并不是我手動設置好的尺寸,而是另外一組不知道怎么計算出來的尺寸值,我靠調試了好久都沒得到我預想的結果……后來我仔細 google 了一番,最后一位 Glide 的 contributor 的話令我茅塞頓開,他在一個 Glide 的 issues 里這樣說道:
fitCenter is the default, see code of ImageView.initImageView()
Note: this is also the reason why Glide shows the aspect-downscaled full image by default (Glide.with.load.into) instead of cropping it.
I'm not sure what happens in Glide when aspect rations of Image, ImageView and .override() are different. For that you can see this.
Exactly, remember the above two steps, the transformation decides what to do. centerCrop() will match the size exactly by throwing away unneeded pixels, and fitCenter() will fit the image inside, but the Bitmap aspect will be different. You can write your own if these defaults don't fit your needs.
嗯大意呢就是說 fitCenter 是 Glide 的默認圖片裁剪技術,這個方法就是縮放圖像讓圖像測量出來等于或小于 ImageView 的邊界范圍。該圖像將會完全顯示,但可能不會填滿整個 ImageView。所以問題就出在這里,我們設置好的圖像尺寸又經過這個方法被計算了一遍,實踐證實即使圖片不是要往 ImageView 中加載這個方法也會起作用!
我們這里手動修改 Glide 的圖片裁剪方法為centerCrop,看結果如何:
val target = object : SimpleTarget<Bitmap>(width,height) { //①
override fun onResourceReady(resource: Bitmap, glideAnimation: GlideAnimation<in Bitmap>) {
src = resource
mMatrix.reset()
invalidate()
}
}
Glide.with(context)
.load(imagePath)
.asBitmap()
.centerCrop()/*.override(width ,height)*/
.into(target) //②
最后代碼成功按預期運行。
完。