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 custo
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;
}
}
There's a very good article on the Android Developer website which helped me alot when I had the same problem with loading large images.
This article explains really well what causes the error and how to solve it. There are also other articles (see menu) to, for example, cache images.