具有相同图像资源的BitmapFactory.decodeStream和BitmapFactory.decodeFile行为

时间:2014-06-25 07:21:02

标签: android image bitmap bitmapfactory remoteview

通过使用方法BitmapFactory.decodeStream(Resources res,int id)和BitmapFactory.decodeFile(String pathName)获取Bitmaps,我有一个奇怪的行为。我想为我的appwidget remoteViews设置一个位图,它是一个319x319px和32kb的png图像,据我所知,它是一个非常小的图像,应该很容易处理。

现在,讨厌的是,如果我把这个图像放在我的drawables文件夹中并想要用BitmapFactory.decodeResource加载位图,应用程序崩溃并且我收到一条错误消息,表明remoteViews超出了最大位图内存使用量。 我发现,以下规则(来自developer.google.com)有最大内存使用量:

 The total Bitmap memory used by the RemoteViews object cannot exceed that 
 required to fill the screen 1.5 times, ie. 
 (screen width x screen height x 4 x 1.5) bytes.

现在到了奇怪的部分:如果我从SD卡加载相同的图像并使用BitmapFactory.decodeFile()解码它,它的工作原理。为什么会这样?

我面临的问题是,如果sd卡中的文件夹中没有其他图像,我必须设置一些默认图像。为此,我将它们放入我的drawables文件夹中。如果我将它们缩小到119x119px,那么它可以工作,我没有收到任何错误消息。但这是非常糟糕的质量,并且在小部件上看起来完全模糊。

任何人都可以解释一下,如何加载位图的行为有何不同?在decodeFile()中是否有任何自动缩放功能不在decodeResource()?

代码的一部分或logcat输出是无关紧要的,所以我不在这里发布,我只是不能理解这种行为而且不知道如何处理它。另外,我搜索了很多关于这个的内容并阅读了API,但我没有找到任何内容。

修改

现在我通过使用上面的公式计算位图内存使用率来修复此问题并检查位图大小如下:

          DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
    double width = (double) metrics.widthPixels;
    double height = (double) metrics.heightPixels;

    double maximumUsage = width * height * 4.0 * 1.5;

    double maximumImageSizeFaktor = (maximumUsage / 3) / 1.5 / 4;
    double maximumImageSize = Math.sqrt(maximumImageSizeFaktor);
    int maxSize = (int) maximumImageSize - 10; //just to get sure, minimize it for 10

    return maxSize;

然后我知道我的位图的最大大小,并可以下采样或调整大小。但这并没有回答这种奇怪的行为。

1 个答案:

答案 0 :(得分:2)

如果BitmapFactory从drawables加载,那么它也会根据设备屏幕进行一些缩放。通过从文件加载不会发生。如果您将图像放在资源文件夹中,它也不会发生。