android - 如何在不出现内存不足异常的情况下获取相对于屏幕尺寸的缩放位图

标签 android bitmap out-of-memory

在我的 Activity 中,我创建了一个宽度和高度与设备分辨率(宽度和高度)相同的位图

我在做什么

Bitmap mBitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888);

screenWidth 和 screenHeight 是

    screenHeight = displaymetrics.heightPixels;
    screenWidth = displaymetrics.widthPixels;

现在,如果我制作此位图,我的堆会增加到 19mb,这不是很好。

告诉我两件事

<强>1。在消耗最少内存的情况下创建相对于屏幕和高度的位图的好方法是什么

<强>2。使用后如何销毁位图?

请提供一点源代码或源代码链接。

最佳答案

  1. 在消耗最少内存的情况下创建相对于屏幕和高度的位图的好方法是什么?

    1. 永远不要创建具有屏幕高度或宽度位图,因为根据设备的密度,它会非常大。而是使用屏幕的 heightwidth 并计算 aspect ratio。现在将 height 固定为一个常数值(例如 1200px),然后根据 aspect ratio 计算 widthImageView 或任何其他 View 将适本地缩放它。
    2. 如果您真的想要透明度,请使用 Bitmap.Config.ARGB_8888,如果不需要,可以使用 RGB_565 或此处列表中的其他内容:http://developer.android.com/reference/android/graphics/Bitmap.Config.html
    3. 如果您不是创建新的 bitmap 而是从某些资源解码 bitmap,请遵循以下几点:
      1. 您需要使用 BitmapFactory.Options.inSampleSize 来减少采样。那么如果您已经知道高度和宽度,如何计算inSampleSize呢?在这里引用:http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
      2. 所以你做了所有这些,但 inSampleSize 仍然不够高,你得到了 OutOfMemoryError ?别担心,如果是这种情况,您需要捕获OutOfMemoryError 并在其中增加您的inSampleSize 并再次进行位图解码.把这个逻辑放在一个循环中,所以崩溃永远不会发生。

  2. 如何在使用后销毁位图?

    1. 这真的很简单。确保调用 Bitmap.recycle() 方法。并删除对位图的所有引用。执行此操作后,资源将被释放,GC 将进行清理。

更新:当您使用 screen_widthscreen_height 创建位图时,您最终会得到一个巨大的位图。而是创建适合整个屏幕的分辨率较低的位图。您可以查看以下代码了解这是如何完成的。

    float screenHeight = displaymetrics.heightPixels;
    float screenWidth = displaymetrics.widthPixels;

    float aspectRatio  = screenWidth/screenHeight;

    int modifiedScreenHeight = 1000;
    int modifiedScreenWidth = (int) (modifiedScreenHeight * aspectRatio);

    Bitmap mBitmap = Bitmap.createBitmap(modifiedScreenWidth, modifiedScreenHeight, Bitmap.Config.ARGB_8888);

现在您得到了具有正确纵横比的位图。您可以使用 ImageView 中的位图来填充整个屏幕。确保为 ImageView 放置 android:scaleType="fitXY"

关于android - 如何在不出现内存不足异常的情况下获取相对于屏幕尺寸的缩放位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33392964/

相关文章:

iphone - iPhone上如何从Bitmap Context中提取RGB分量?

java - 在Android中同时从多个Firebase数据库引用中检索数据

android - 如何在 mpandroidChart 的条形图中隐藏 x 轴值

android - 果冻 bean 通知操作已禁用

android - 如何从我们的应用程序中删除图像?

java - 在 Java 中设置堆大小

java - 隐藏屏幕上方的 ImageView/以编程方式将 y 位置设置为负值

java - 如何制作像 uber 这样的标记标签?

java - 如何查找javac任务中的内存泄漏

performance - HashMap 和 Vec 之间的内存高效转换