当从Android Gallery(使用startActivityForResult)加载"大"图像(> 1.5MB)时,我使用Picasso获得Out Of Memory异常.
我正在使用自定义Target对象,因为我需要在Bitmap准备好时对其进行预处理,并且我还使用自定义Transform对象来缩放Bitmap.
问题是public Bitmap transform(Bitmap source)我的Transform对象上的方法永远不会被调用,因为Out Of Memory Exception,所以我没有机会重新采样图像.
但是,如果我使用该.resize(maxWidth, maxHeight)方法,那么它加载图像确定.我认为Transform对象也是出于这个目的,但似乎在调整大小后调用transform方法,如果我不调用resize,那么它将以Out of Memory结束.
问题是,使用resize我需要指定宽度和高度,但我需要缩放并保持纵横比.
考虑到图像将从用户图库中选择,因此它们可以更大或更小,纵向,平方或横向等,因此我需要自己的Transformation对象来执行需要我的应用程序的逻辑.
edr*_*ian 59
我找到了解决方案..
在我的Transform对象中,我需要将图像(保持纵横比)缩放到1024 x 768 max.
除非我调用.resize(width, height)重新取样图像,否则永远不会调用变换对象.
为了保持宽高比和使用调整大小我打电话.centerInside().这样,图像将被缩放重新采样以适合宽度,高度).
我给.resize(宽度,高度)的值是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);
Run Code Online (Sandbox Code Playgroud)
这是我的自定义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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
23979 次 |
| 最近记录: |