In the last blog posts, you've learned how to load images from various sources and how to use different kind of placeholders. This week's blog post is important if you cannot influence the size of the image to be loaded: resizing and scaling!
Picasso Series Overview
- Placeholders, Errors, and Fading
- Image Resizing, Scaling and fit()
- Callbacks, RemoteViews and Notifications
- Advanced ListViews With Images
- Image Loading for RecyclerView and CardView
Image Resizing with resize(x, y)
Generally it's optimal if your server or API deliver the image in the exact dimensions you need, which are a perfect trade-off between bandwidth, memory consumption and image quality.
Unfortunately, it's not always in your control to request images in the perfect dimensions. If the images are in a weird size you can use the resize(horizontalSize, verticalSize)
call to change the dimensions of your image into a more suitable size. This will resize the image before displaying it in the 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);
Use of scaleDown()
When using the resize()
option Picasso will also upscale your image. Since making a small image bigger without improving the quality of the image can be wasted computing time, call scaleDown(true)
to only apply the resize()
when the original image has larger dimensions than the target size.
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);
Avoiding Stretched Images with Scaling
Now, as with any image manipulation, resizing images can really distort the aspect ratio and uglify the image display. In most of your use cases, you want to prevent this from happening. Picasso gives you two mitigation choices here, either call centerCrop()
or centerInside()
.
CenterCrop
CenterCrop()
is a cropping technique that scales the image so that it fills the requested bounds of the ImageView
and then crops the extra. The ImageView
will be filled completely, but the entire image might not be displayed.
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.resize(600, 200) // resizes the image to these dimensions (in pixel)
.centerCrop()
.into(imageViewResizeCenterCrop);
CenterInside
CenterInside()
is a cropping technique that scales the image so that both dimensions are equal to or less than the requested bounds of the ImageView
. The image will be displayed completely, but might not fill the entire ImageView
.
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.resize(600, 200)
.centerInside()
.into(imageViewResizeCenterInside);
Last, but not least: Picasso's fit()
The discussed options should cover your needs for functionality regarding image resizing and scaling. There is one last helper functionality of Picasso, which can be very useful: fit()
.
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.fit()
// call .centerInside() or .centerCrop() to avoid a stretched image
.into(imageViewFit);
fit()
is measuring the dimensions of the target ImageView
and internally uses resize()
to reduce the image size to the dimensions of the ImageView
. There are two things to know about fit()
. First, calling fit()
can delay the image request since Picasso will need to wait until the size of the ImageView
can be measured. Second, you only can use fit()
with an ImageView
as the target (we'll look at other targets later).
The advantage is that the image is at the lowest possible resolution, without affecting its quality. A lower resolution means less data to be hold in the cache. This can significantly reduce the impact of images in the memory footprint of your app. In summary, if you prefer a lower memory impact over a little faster loading times, fit()
is a great tool.
Outlook
In this blog post, you've learned how to make adjustments to the size and display of images. This should be very helpful for creating great apps. There is one more tool to make the images in your app feel even more fluid: loading important images first. Picasso offers that functionality with request priorities, which we'll describe in the next blog post.