Load large images with Picasso and custom Transform object

前端 未结 2 1630
借酒劲吻你
借酒劲吻你 2020-11-28 06:34

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

2条回答
  •  醉话见心
    2020-11-28 07:20

    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;
        }
    
    }
    

提交回复
热议问题