一般的情况下,如果你的服务器或者API能够按需提供精确尺寸的图像,并且能够在带宽,内存消耗和图像质量之间做出完美的权衡,那简直不能更幸运了。
不幸的是,对图像尺寸的要求,不可能完全受控制。如果图像的尺寸很怪异,可以使用.resize(horizontalSize, verticalSize)来改变图像的大小到一个合适的尺寸。它会在展示到ImageView上之前重新调整尺寸的大小。
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.resize(600, 200) // resizes the image to these dimensions (in pixel). does not respect aspect ratio
.into(imageViewResize);当使用resize()选项时,Picasso可能会放大你的图像。如果不改善图像质量,而仅仅是将小图放大,是非常浪费计算时间的,可以使用.onlyScaleDown()只对那些当原始图像尺寸大于目标控件尺寸的用例中,这种情况下,Picasso才会对图像进行尺寸重调整。
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.resize(6000, 2000)
.onlyScaleDown() // the image will only be resized if it's bigger than 6000x2000 pixels.
.into(imageViewResizeScaleDown);现在,对于任何图像处理来讲,调整图片大小都会扭曲纵横比,丑化图像的显示。绝大多数情况下,你都不希望这类事情的发生。Picasso提供了两套缓解方案,要么调用.centerCrop(),要么调用.centerInside()。
CenterCrop()属于裁剪技术的一种,它允许图像缩放,以便能够充满目标ImageView的边界,并裁剪多余的部分。ImageView将会被完全充满,但是对于图片自身来讲,可能不会被完整的展示出来。
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.resize(600, 200) // resizes the image to these dimensions (in pixel)
.centerCrop()
.into(imageViewResizeCenterCrop);CenterInside()属于另一种裁剪技术,同样会缩放图像,以便缩放后的图像尺寸等于或小于目标ImageView的边界。图像将会完整展示,但不能保证图像能够填满整个ImageView边界。
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.resize(600, 200)
.centerInside()
.into(imageViewResizeCenterInside);我们刚刚所讨论过的那些选项,基本能够满足你在尺寸调整和缩放时要求。在这方面,Picasso还有最后一个非常有用的函数,fit()。
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.fit()
// call .centerInside() or .centerCrop() to avoid a stretched image
.into(imageViewFit);fit()将测量目标ImageView的尺寸,并且在内部实现中调用resize(),用来将图像尺寸适配至目标ImageView的大小。关于fit()有两件事需要了解。第一,因为Picasso需要等待目标ImageView的测量完成,所以fit()可能会延迟加载图像。第二,使用fit()的前提条件是:只能是ImageView作为加载的target(我们将会在随后介绍其他target)。
在不影响图像质量的前提下,应该尽量降低图像的分辨率。因为低分辨率意味着更少的数据被缓存。这能够显著降低因图片占用而对App性能所造成的影响。概括来说,如果你更倾向于通过降低内存占用来达到快速加载的目的,fit()是个不错的选择。