Load large images with Picasso and custom Transform object
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;
}
}
Picasso, image loading and resizing
Picasso
will only resize()
the image once because it will be cached (specifically stored in the LruCache) unless the cache reached the maximum limit your cache will remove an image so that it can store new ones. Accessing the deleted image again will trigger another resize()
call but for those image that are still in cache Picasso will not need to perform a resize()
.
If you have a full control to your server it would be better if you can create an API that has customizable image-size-parameter. Let say you only need a thumbnail image therefore you will just provide the width-height of your image rather than downloading a large image which do not give benefits on thumbnails plus you save some bandwidth.
Will Picasso's fit(), resize(), and transform() downsize images before downloading?
I also work with Picasso, and my answer is "no". Images are always being downloaded first, then resized/transformed, then displayed.
The only way to download a reduced size (to be displayed in ListView) is to provide a smaller size or thumbnail version of the image. It is easy to achieve if you host the images in your own server.
Related Topics
Detect If an App Is Installed from Play Store
How to Finish an Android Application
Android Set Button Background Programmatically
Read Command Output Inside Su Process
Register to Be Default App for Custom File Type
Detect When Android V2 Maps Has Loaded
Android Opengl Es Transparent Background
Android Action_Shutdown Broadcast Not Working
How to Connect SQL Server Using Jtds Driver in Android
Does Setwidth(Int Pixels) Use Dip or Px
Android SQLite Database, Why Drop Table and Recreate on Upgrade
Android Kitkat 4.4 Hangouts Cannot Handle Sending Sms Intent
Android: How to Monitor Wifi Signal Strength
Upgraded to Android Studio 3.4 - Aapt2Internalexception: Aapt2: Daemon Startup Failed
Display All Unicode Chars in Textview
How to Play an Mp3 in the Res/Raw Folder of My Android App
How to Get Documents in an Android Directory That Phonegap Will See