Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Download image and resize to avoid OOM errors, Picasso fit() distorts image

I am trying to show images in a full screen view and using the following code:

// Target to write the image to local storage.
Target target = new Target() {
   // Target implementation.
}

// (1) Download and save the image locally.
Picasso.with(context)
       .load(url)
       .into(target);

// (2) Use the cached version of the image and load the ImageView.
Picasso.with(context)
       .load(url)
       .into(imgDisplay);

This code works well on newer phones, but on phones with 32MB VMs, I get out of memory issues. So I tried changing (2) to:

    Picasso.with(context)
       .load(url)
       .fit()
       .into(imgDisplay);

This resulted in distorted images. Since I do not know the dimensions of the image until it is downloaded, I cannot set the ImageView dimensions, and hence the image is being resized without any consideration to aspect ratio in to my ImageView:

    <ImageView
    android:id="@+id/imgDisplay"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scaleType="fitCenter"
    android:layout_alignParentTop="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />

What is the best way to handle this situation? My original images have max width 768, and height 1024, and I want to downsample when the screens are much smaller than this. If I try to use resize(), my code becomes complicated, as I have to wait for (1) to finish the download and then add the resize() in (2).

I am assuming Transformations do not help in this case, as the input to public Bitmap transform(Bitmap source) will already have the large bitmap which will cause me to run out of memory.

like image 832
wislo Avatar asked May 03 '15 06:05

wislo


People also ask

How do I change the size of a Picasso image?

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. When using the resize () option Picasso will also upscale your image.

How does fit() work in Picasso?

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.

How do I crop an image in Picasso?

Picasso gives you two mitigation choices here, either call centerCrop () or centerInside (). 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.

How to resize an image online?

To resize an image, first choose the photo from the Choose File option. Enter the image size to 100kb, 50kb or you want to resize. Adjust the quality slider to Reduce Photo size online. then click "Resize Image" button. After the image has been processed, you will be given the option to "Download Image" to save it to your device.


1 Answers

You can combine fit() with centerCrop() or centerInside(), depending on how you want the image to fit your View:

Picasso.with(context)
   .load(url)
   .fit()
   .centerCrop()
   .into(imgDisplay);

Picasso.with(context)
   .load(url)
   .fit()
   .centerInside()
   .into(imgDisplay);
like image 178
Sebastiano Avatar answered Sep 28 '22 00:09

Sebastiano