gpt4 book ai didi

android - BitmapFactory.decodeStream 内存不足,尽管使用了减少的样本大小

转载 作者:可可西里 更新时间:2023-11-01 19:09:03 25 4
gpt4 key购买 nike

我看了很多关于解码位图的内存分配问题的相关帖子,但使用官网提供的代码仍然无法找到以下问题的解决方案。

这是我的代码:

public static Bitmap decodeSampledBitmapFromResource(InputStream inputStream, int reqWidth, int reqHeight) {

ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
try {
while ((len = inputStream.read(buffer)) > -1) {
baos.write(buffer, 0, len);
}
baos.flush();
InputStream is1 = new ByteArrayInputStream(baos.toByteArray());
InputStream is2 = new ByteArrayInputStream(baos.toByteArray());

final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is1, null, options);

options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inPurgeable = true;
options.inInputShareable = true;
options.inJustDecodeBounds = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
return BitmapFactory.decodeStream(is2, null, options);

} catch (Exception e) {
e.printStackTrace();

return null;
}
}

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) {

// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);

// Choose the smallest ratio as inSampleSize value, this will guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}


return inSampleSize;
}

bitmap = decodeSampledBitmapFromResource(inputStream, 600, 600);

我在这一行中收到“3250016 字节分配内存不足错误”:

return BitmapFactory.decodeStream(is2, null, options);

在我看来,3.2 MB 足够小,可以分配。我哪里错了?我该如何解决这个问题?

编辑

查看此解决方案后 HERE由 N-Joy 提供,它适用于所需尺寸 300,但我需要的尺寸是 800,所以我仍然遇到错误。

最佳答案

decodeSampledBitmapFromResource 方法内存效率不高,因为它使用 3 个流:ByteArrayOutputStream baos、ByteArrayInputStream is1 和 ByteArrayInputStream is2,它们中的每一个都存储相同的流图像的数据(每个字节数组)。

当我用我的设备 (LG nexus 4) 测试将 SD 卡上的 2560x1600 图像解码为目标尺寸 800 时,它需要这样的东西:

03-13 15:47:52.557: E/DecodeBitmap(11177): dalvikPss (beginning) = 1780
03-13 15:47:53.157: E/DecodeBitmap(11177): dalvikPss (decoding) = 26393
03-13 15:47:53.548: E/DecodeBitmap(11177): dalvikPss (after all) = 30401 time = 999

我们可以看到:为解码 4096000 个像素图像分配了太多内存 (28.5 MB)。

解决方案:我们读取 InputStream 并将数据直接存储到一个字节数组中,并使用这个字节数组进行其余工作。
示例代码:

public Bitmap decodeSampledBitmapFromResourceMemOpt(
InputStream inputStream, int reqWidth, int reqHeight) {

byte[] byteArr = new byte[0];
byte[] buffer = new byte[1024];
int len;
int count = 0;

try {
while ((len = inputStream.read(buffer)) > -1) {
if (len != 0) {
if (count + len > byteArr.length) {
byte[] newbuf = new byte[(count + len) * 2];
System.arraycopy(byteArr, 0, newbuf, 0, count);
byteArr = newbuf;
}

System.arraycopy(buffer, 0, byteArr, count, len);
count += len;
}
}

final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(byteArr, 0, count, options);

options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
options.inPurgeable = true;
options.inInputShareable = true;
options.inJustDecodeBounds = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;

int[] pids = { android.os.Process.myPid() };
MemoryInfo myMemInfo = mAM.getProcessMemoryInfo(pids)[0];
Log.e(TAG, "dalvikPss (decoding) = " + myMemInfo.dalvikPss);

return BitmapFactory.decodeByteArray(byteArr, 0, count, options);

} catch (Exception e) {
e.printStackTrace();

return null;
}
}

进行计算的方法:

public void onButtonClicked(View v) {
int[] pids = { android.os.Process.myPid() };
MemoryInfo myMemInfo = mAM.getProcessMemoryInfo(pids)[0];
Log.e(TAG, "dalvikPss (beginning) = " + myMemInfo.dalvikPss);

long startTime = System.currentTimeMillis();

FileInputStream inputStream;
String filePath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/test2.png";
File file = new File(filePath);
try {
inputStream = new FileInputStream(file);
// mBitmap = decodeSampledBitmapFromResource(inputStream, 800, 800);
mBitmap = decodeSampledBitmapFromResourceMemOpt(inputStream, 800,
800);
ImageView imageView = (ImageView) findViewById(R.id.image);
imageView.setImageBitmap(mBitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
myMemInfo = mAM.getProcessMemoryInfo(pids)[0];
Log.e(TAG, "dalvikPss (after all) = " + myMemInfo.dalvikPss
+ " time = " + (System.currentTimeMillis() - startTime));
}

结果:

03-13 16:02:20.373: E/DecodeBitmap(13663): dalvikPss (beginning) = 1823
03-13 16:02:20.923: E/DecodeBitmap(13663): dalvikPss (decoding) = 18414
03-13 16:02:21.294: E/DecodeBitmap(13663): dalvikPss (after all) = 18414 time = 917

关于android - BitmapFactory.decodeStream 内存不足,尽管使用了减少的样本大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15254272/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com