我正在使用android-crop库。如果用户试图从大图像(手机摄像头的图像)裁剪,我正在处理令人沮丧的内存不足。
我试图压缩生成的位图,但在尝试压缩位图时仍然会得到OutOfMemoryError
。这里是我的代码:请让我知道我做错了什么和/或如何防止这种内存不足错误?
private void handleCrop(int resultCode, Intent result) {
if (resultCode == RESULT_OK) {
if (mBitmap != null) {
mBitmap.recycle();
mBitmap = null;
}
Bitmap temp; //temporary bitmap
try {
temp = MediaStore.Images.Media.getBitmap(getContentResolver()
, Crop.getOutput(result)); //load image from URI
ByteArrayOutputStream out = new ByteArrayOutputStream();
temp.compress(Bitmap.CompressFormat.JPEG, 60, out);
mBitmap = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray()));
out.close();
temp.recycle();
temp = null;
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "error loading photo. please try with another photo"
, Toast.LENGTH_SHORT).show();
return;
}
if (mBitmap != null) {
mImageViewProfilePhoto.setImageBitmap(mBitmap);
enableFinalization();
}
}
}
感谢Gabe的观点,我可以解决这个问题:
private void handleCrop(int resultCode, Intent result) {
if (resultCode == RESULT_OK) {
if (mBitmap != null) {
mBitmap.recycle();
mBitmap = null;
}
try {
mBitmap = MediaStore.Images.Media.getBitmap(getContentResolver()
, Crop.getOutput(result)); //load image from URI
File tempImageFile = new File(mContext.getFilesDir().getAbsolutePath()
, "temp_1311_14_hahahah_lol_WTF_shit_1414.bin");
FileOutputStream out = new FileOutputStream (tempImageFile);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 30, out);
mBitmap.recycle();
mBitmap = null;
mBitmap = BitmapFactory.decodeFile(tempImageFile.getPath());
boolean deleted = tempImageFile.delete();
out.close();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "error loading photo. please try with another photo"
, Toast.LENGTH_SHORT).show();
return;
}
if (mBitmap != null) {
mImageViewProfilePhoto.setImageBitmap(mBitmap);
enableFinalization();
}
} else if (resultCode == Crop.RESULT_ERROR) {
Toast.makeText(this, Crop.getError(result).getMessage(), Toast.LENGTH_SHORT).show();
disableFinalization();
}
}
希望它对其他人有用。
答案 0 :(得分:1)
假设问题不在你的应用程序的其他地方(并且它总是可以与OOM一起) - 如果你有一个大图像,你基本上可以制作3份副本。第一个是原始的,第二个是你的ByteArrayOutputStream,第三个是你的decodeStream。如果图像很大(如10MB +),那么单独会导致问题。我建议使用基于磁盘的输出流,看看是否能解决问题。此外,您可以在temp.recycle之后调用decodeStream调用,以确保您一次不会有2个完整副本。