我正在开发游戏,我使用Bitmap files
加载52 BitmapFactory
,并在运行应用时。我收到了OutOfMemoryError
。那是因为drawable
文件夹中的图片是.JPG
而不是.PNG
吗?请让我知道如何解决这个问题。
答案 0 :(得分:1)
JPG与PNG无关,因为当您加载位图时,将它们解压缩为原始数据(基本上与bmp相同)。未压缩,每个位图使用4 *宽*高度字节。根据图像的大小,可能会非常大。我建议使用一个固定大小的LRUCache,只保存你在内存中实际需要的图像并踢出未使用的图像。
答案 1 :(得分:0)
我正在处理我的应用程序中的196张png图片,当我尝试加载所有图片时也遇到了内存不足。我的图像是png,这意味着将它们从jpg转换为png没有帮助。
我不知道它是否是最佳解决方案,但我所做的是从我的主要活动的OnCreate()方法开始一个IntentService,第一次调用它。在内部,我检查内部存储器上是否已存储较小版本的图像。如果已经创建了较小的版本,我会维护它们的列表,并在我需要显示它们时在我的活动中使用它们。如果它们不存在(当用户第一次安装应用程序时发生,或者从此应用程序的设置中清除缓存),我通过调用具有所需宽度和高度的decodeSampledBitmapFromResource()
来创建它们。所需的宽度和高度可以存储在xml文件中,并且特定于不同的屏幕。下面提供了我在维护图像方面时用于调整大小的功能。
/**
* Calculate in sample size.
*
* @param options the options
* @param reqWidth the req width
* @param reqHeight the req height
* @return the int
*/
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
/**
* Decode sampled bitmap from resource.
*
* @param res the res
* @param resId the res id
* @param reqWidth the req width
* @param reqHeight the req height
* @return the bitmap
*/
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}