Load large images with Picasso and custom Transform object

edrian

I'm getting an Out Of Memory exception using Picasso when loading "large" images (> 1.5MB) from Android Gallery (using startActivityForResult).

I'm using a custom Target object because I need to preprocess the Bitmap when it is ready and also I'm using a custom Transform object to scale the Bitmap.

The problem is that the method public Bitmap transform(Bitmap source) on my Transform object is never called because the Out Of Memory Exception, so I don't get the oportunity to resample the image.

But, if I use the .resize(maxWidth, maxHeight) method, then it loads the image OK. I supossed that the Transform object was for that purpose too, but it seems that the transform method is called after the resize, and, if I don't call resize, then it will end in an Out of Memory..

The problem is that with resize I need to specify both width and height, but I need to scale and keep the aspect ratio.

Consider that the images will be selected from user Gallery, so they can be bigger or smaller, portrait, squared or landscape, etc, so I need my own Transformation object to perform the logic that needs my application.

edrian

I found a solution..

In my Transform object I needed to scale the image (keeping aspect ratio) to 1024 x 768 max.

Transform object was never called unless I call .resize(width, height) to resample down the image.

For keeping aspect ratio and using resize I call .centerInside(). This way image will be scaled resample to fit width, height).

The value that I give to .resize(width, height) is Math.ceil(Math.sqrt(1024 * 768)). This way I'm sure to have an image higher enough for my custom Transform object, and also avoid Out Of Memory exception

Update: Full example

Following this example you will get a image that fits inside MAX_WIDTH and MAX_HEIGHT bounds (keeping aspect ratio)

private static final int MAX_WIDTH = 1024;
private static final int MAX_HEIGHT = 768;

int size = (int) Math.ceil(Math.sqrt(MAX_WIDTH * MAX_HEIGHT));

// Loads given image
Picasso.with(imageView.getContext())
    .load(imagePath)
    .transform(new BitmapTransform(MAX_WIDTH, MAX_HEIGHT))
    .skipMemoryCache()
    .resize(size, size)
    .centerInside()
    .into(imageView);

And this is my custom BitmapTransform class:

import android.graphics.Bitmap;
import com.squareup.picasso.Transformation;

/**
 * Transformate the loaded image to avoid OutOfMemoryException
 */
public class BitmapTransform implements Transformation {

    private final int maxWidth;
    private final int maxHeight;

    public BitmapTransform(int maxWidth, int maxHeight) {
        this.maxWidth = maxWidth;
        this.maxHeight = maxHeight;
    }

    @Override
    public Bitmap transform(Bitmap source) {
        int targetWidth, targetHeight;
        double aspectRatio;

        if (source.getWidth() > source.getHeight()) {
            targetWidth = maxWidth;
            aspectRatio = (double) source.getHeight() / (double) source.getWidth();
            targetHeight = (int) (targetWidth * aspectRatio);
        } else {
            targetHeight = maxHeight;
            aspectRatio = (double) source.getWidth() / (double) source.getHeight();
            targetWidth = (int) (targetHeight * aspectRatio);
        }

        Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
        if (result != source) {
            source.recycle();
        }
        return result;
    }

    @Override
    public String key() {
        return maxWidth + "x" + maxHeight;
    }

}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Load large images with Picasso and custom Transform object

From Dev

Load multiple images with picasso - Android

From Dev

Picasso Taking time to load images

From Dev

Set maximum width to load images with Picasso

From Dev

Generate cards with cardslib and load images with picasso

From Dev

Load Images by passing authentication token Picasso Xamarin

From Dev

Picasso is not loading the images from url with custom adapter

From Dev

Will Picasso's fit(), resize(), and transform() downsize images before downloading?

From Dev

lazy load with large number of images

From Dev

Large images (from file) not loading in Picasso, no obvious error seen

From Dev

Picasso don't load images from drawable (Android)

From Dev

Using Picasso to Load Images in List Crashes app on Scroll

From Dev

Load Images from Phone storage to GridView using Picasso

From Dev

How can I load images using Picasso from a RecyclerAdapter?

From Dev

How to correctly implement a custom listview with images using Picasso library?

From Dev

Fastest way to preload/load large images

From Dev

Unable to load large images into web view android

From Dev

Unable to load large images into web view android

From Dev

Picasso large image download

From Dev

Picasso large image download

From Dev

Picasso Library and GridView Images

From Dev

Fetch images with Callback in Picasso?

From Dev

Picasso Images not loading in a GridView

From Dev

Picasso not showing images

From Dev

Picasso loading duplicate images

From Dev

Clearing Picasso images cache

From Dev

Picasso Images not loading in a GridView

From Dev

Picasso - keeping images on disk

From Dev

Picasso not showing images

Related Related

HotTag

Archive