我在使用 Picasso 从 Android 图库(使用 startActivityForResult)加载“大”图像 (> 1.5MB) 时遇到内存不足异常。
我正在使用自定义 Target 对象,因为我需要在 Bitmap 准备好时对其进行预处理,并且我正在使用自定义 Transform 对象来缩放 Bitmap。
问题是我的 Transform 对象上的方法 public Bitmap transform(Bitmap source)
因为内存不足异常而从未被调用,所以我没有机会重新采样图像。
但是,如果我使用 .resize(maxWidth, maxHeight)
方法,那么它可以正常加载图像。我猜Transform对象也是为了这个目的,但是似乎在resize之后调用了transform方法,如果我不调用resize,那么它将以Out of Memory结束..
问题是调整大小时我需要指定宽度和高度,但我需要缩放并保持纵横比。
考虑到图像将从用户图库中选择,因此它们可以更大或更小、纵向、正方形或横向等,因此我需要自己的 Transformation 对象来执行需要我的应用程序的逻辑。
最佳答案
我找到了解决办法..
在我的 Transform 对象中,我需要将图像(保持纵横比)缩放到最大 1024 x 768。
除非我调用 .resize(width, height)
来重新采样图像,否则从未调用过变换对象。
为了保持纵横比和使用调整大小,我调用 .centerInside()
。这样图像将被缩放重新采样以适应宽度、高度)。
我给 .resize(width, height) 的值是 Math.ceil(Math.sqrt(1024 * 768))
。
这样我就可以确保我的自定义 Transform 对象的图像足够高,并且还可以避免 Out Of Memory 异常
更新:完整示例
按照此示例,您将获得适合 MAX_WIDTH 和 MAX_HEIGHT 范围内的图像(保持纵横比)
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);
这是我的自定义 BitmapTransform 类:
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;
}
}
关于android - 使用 Picasso 和自定义 Transform 对象加载大图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23740307/