我就不废话了,直接贴代码:
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) //②
最后代码成功按预期运行。
完。
网友评论