Android 使用毕加索和自定义变换对象加载大型图像
在从Android Gallery(使用startActivityForResult)加载“大”图像(>1.5MB)时,我使用毕加索遇到内存不足异常 我使用一个自定义目标对象,因为我需要在位图准备就绪时对其进行预处理,而且我还使用一个自定义变换对象来缩放位图 问题是,由于内存不足异常,我的transform对象上的方法Android 使用毕加索和自定义变换对象加载大型图像,android,picasso,Android,Picasso,在从Android Gallery(使用startActivityForResult)加载“大”图像(>1.5MB)时,我使用毕加索遇到内存不足异常 我使用一个自定义目标对象,因为我需要在位图准备就绪时对其进行预处理,而且我还使用一个自定义变换对象来缩放位图 问题是,由于内存不足异常,我的transform对象上的方法public Bitmap transform(Bitmap source)从未被调用,因此我没有机会对图像重新采样 但是,如果我使用.resize(maxWidth,maxHei
public Bitmap transform(Bitmap source)
从未被调用,因此我没有机会对图像重新采样
但是,如果我使用.resize(maxWidth,maxHeight)
方法,那么它会加载图像OK。我猜Transform对象也是为了这个目的,但是似乎在resize之后调用了Transform方法,如果我不调用resize,那么它将以内存不足结束
问题是,使用resize时,我需要指定宽度和高度,但我需要缩放并保持纵横比
考虑到图像将从用户库中选择,因此它们可以更大或更小、纵向、方形或横向等,因此我需要自己的转换对象来执行需要我的应用程序的逻辑 Android开发者网站上有一篇非常好的文章,当我在加载大图像时遇到同样的问题时,这篇文章对我帮助很大 这篇文章很好地解释了错误的原因以及如何解决它。还有其他文章(请参见菜单)可用于缓存图像 我找到了一个解决办法 在我的Transform对象中,我需要将图像缩放(保持纵横比)到最大1024 x 768 除非调用
.resize(width,height)
对图像进行重采样,否则从未调用Transform对象
为了保持纵横比并使用resize,我调用.centerInside()
。这样,图像将被缩放(重新采样以适应宽度、高度)
我给.resize(宽度、高度)的值是Math.ceil(Math.sqrt(1024*768))
。
通过这种方式,我可以确保我的自定义变换对象的图像足够高,并且还可以避免内存不足的异常
更新:完整示例
在本例中,您将获得一幅符合最大宽度和最大高度界限(保持纵横比)的图像
这是我的自定义位图转换类:
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;
}
}
宽度和高度的Math.ceil(Math.sqrt(1024*768))?是的,@DayDayHappy。我举了一个例子。我希望它能帮助我解决同样的问题,感谢那篇有用的帖子,我终于找到了解决办法。非常感谢,伙计。感谢这个转换是使用毕加索的正确实现方式。你可以调用
.fit()
,而不是.resize()
,这会更快,但会降低图像质量。你能提供你所指文章的链接吗?
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;
}
}