在Android中显示来自SD卡的大图像

7
在Android中,如何从SD卡中显示一张图片(任意大小),而不会出现内存不足错误?是否需要先将图像放入媒体库中?
如果设备允许的内存水平越大,则显示的图像就越大。以下是伪代码示例:

尝试遵循Google推荐的步骤:http://developer.android.com/training/displaying-bitmaps/index.html - Longerian
4个回答

13

编辑:这个问题已经在加载图像到位图对象时出现奇怪的内存不足问题 (前两个得票最高的答案) 中得到了解答。它也使用了inSampleSize选项,但是提供了一个小方法来自动获取适当的值。

我的原始回答:

BitmapFactory.Options类中的inSampleSize可以解决您的问题(http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize)。它通过创建一个结果宽度和高度为原始宽度和高度的1/inSampleSize的位图来工作,从而减少内存消耗(通过inSampleSize^2?)。在使用之前,您应该阅读文档。

示例:

BitmapFactory.Options options = new BitmapFactory.Options();
// will results in a much smaller image than the original
options.inSampleSize = 8;

// don't ever use a path to /sdcard like this, but I'm sure you have a sane way to do that
// in this case nebulae.jpg is a 19MB 8000x3874px image
final Bitmap b = BitmapFactory.decodeFile("/sdcard/nebulae.jpg", options);

final ImageView iv = (ImageView)findViewById(R.id.image_id);
iv.setImageBitmap(b);
Log.d("ExampleImage", "decoded bitmap dimensions:" + b.getWidth() + "x" + b.getHeight()); // 1000x485

然而,在这里,它只适用于尺寸不超过inSampleSize的平方倍允许内存大小的图片,并且会降低小图片的质量。诀窍在于找到合适的inSampleSize值。


感谢Gautier的回答。你链接中排名最高的两个答案使用一个常量来确定图像的最大尺寸。是否有一种方法可以根据设备的内存水平来确定这个值? - hpique
确实如此,但您可能会将图像用于具有有限尺寸的ImageView,如果您的图像大于此尺寸,则只会浪费(宝贵的!)内存。 - Gautier Hayoun

4

我使用以下代码来显示各种大小的图像:

ImageView imageView=new ImageView(this);
imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageView.setAdjustViewBounds(true);
FileInputStream fis=new FileInputStream(file);
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize=2; //try to decrease decoded image
options.inPurgeable=true; //if necessary purge pixels into disk
options.inScaled=true; //scale down image to actual device density
Bitmap bm=BitmapFactory.decodeStream(is, null, options);
imageView.setImageBitmap(bm);
fis.close();

这个程序目前运行良好,但有时会出现OutOfMemory错误。错误率为15次尝试中的1次。所以,请问您能否建议需要进行额外配置以避免这个错误?我的意思是让它100%可靠。 - Chandra Sekhar

2

例如:

yourImgView.setImageBitmap(BitmapFactory.decodeFile("/sdcard/1.jpg"));

0

而且,那篇文章远远不足以让你了解如何在Android上处理图像。 - hpique
好的,你提出了一些很好的观点... 但它确实回答了所问的问题... 或许可以提出另一个问题,如何加载一个大于可用内存的图像? - PearsonArtPhoto
1
问题明确指出了内存问题,但为了避免歧义,我澄清了标题。 - hpique

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接