Android Bitmap加载内存错误Galaxy S3 WXGA

Hun*_*ers 24 android bitmap

如果有人能够确认我已正确解决了以下问题或者是否有替代解决方案,我将非常感激?

我有一个应用程序将大图像(例如800*1720像素)加载到内存中并以滚动视图显示它.图像是博物馆的平面图,我想要一个简单的地图,如滚动和缩放的体验.图像在旧设备上正常加载,但在三星Galaxy S3上导致内存不足错误.

看看LogCat消息,结果发现在创建位图时,22MB正在为位图而不是800*1720*4 = 5.5MB进行分配.基本上按其他设备的要求分配了4倍的内存,并将内存使用量推到50MB堆大小.

此问题的推荐解决方案是使用该BitmapFactory.Options.inSampleSize选项来降低加载的图像的分辨率并使其需要更少的内存.但是,这会降低图像的质量,我实际上希望以原始质量显示它的全尺寸,因为在旧设备上工作正常.

经过多次刮擦后我得出结论,问题是S3的WXGA屏幕上的像素密度是2.0,因此对于图像中的每个像素,位图实际上分配了4个像素.通过一些试验和错误,我发现我可以通过设置来防止这种情况发生options.inScaled = false;

http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inScaled

在途中,我还意识到我可以通过设置使用2像素而不是4像素的低保真色彩深度将我的内存使用量减半到2.7MB options.inPreferredConfig = Bitmap.Config.RGB_565;.对于我的地板,这不会影响可见的图像质量.

最终的代码是这样的:

String uri = "drawable/floorplan";
int imageResource = getResources().getIdentifier(uri, null, getPackageName());
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
options.inScaled = false;
Bitmap bm = BitmapFactory.decodeResource(getResources(), imageResource, options);
IVfloorplan.setImageBitmap(bm);
Run Code Online (Sandbox Code Playgroud)

显示此位图时,您需要将其缩放.要计算缩放比例,您可以从以下位置获取像素密度:

float density = getResources().getDisplayMetrics().density;
Run Code Online (Sandbox Code Playgroud)

我将位图的内存使用量从22MB减少到2.7MB,这在50MB堆中非常重要.

Joe*_*nte 2

S3的屏幕分辨率非常高,所以这是可以理解的。此外,如果图像位于可绘制文件夹中,它可能会自动放大。可能有一些方法可以将其关闭。即使您的图像大小不变,操作系统也必须分配一个缓冲区来容纳图像,也可能分配一个缓冲区来容纳在屏幕上显示它。

另一种方法是使用平铺,它用于 SNES 游戏等游戏中。这也是他们在不耗尽 RAM 的情况下处理大量图形的方法。有证据表明,谷歌地图就是这样绘制地球地图的。您基本上将大图像切成图块,并在平移到它们时在屏幕上显示图块(当然,可能每侧都有 1 个额外的图块)。

尽管这是后蜂巢时代,Google 编写了代码来更好地管理位图分配,但要小心位图分配。它更像是一个 C 程序而不是 Java 程序,并且像管理它一样管理它是一个好主意。在Android中使用Bitmap对象时很容易耗尽堆空间