下面的代码可以导致OutOfMemory吗?我认为它允许超出应用程序内存限制。
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
image = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), matrix, true);
在Android中旋转图片的最佳方法是什么?
在新进程的服务中分配它以获得更多堆?
@CommonsWare在这个链接[1]中说,许多开发人员认为更多的堆是低效编码的解决方案。
这个问题也表明大堆[2]。
是否有更简单的解决方案?
答案 0 :(得分:2)
简短的回答是,是的,此代码可能会导致OutOfMemory。我认为没有比增加app堆大小更简单的解决方案。我相信@CommonsWare是正确的,并且OutOfMemory经常表示编程错误。但是在某些情况下,你需要,嗯,巨大的记忆。旋转巨大的图像绝对是这种情况之一。
您可以使用本机代码(NDK)而不是要求增加堆大小,但这绝对不容易。它仍然需要大量内存,因此使用C ++没有任何优势(除了它适用于2.3)。
答案 1 :(得分:1)
如果您希望使用基于NDK的解决方案,我创建了一个here,并且我已经创建了一个github项目here。
这样可以通过将数据放入本机C“world”来避免OOM,回收旧数据,并在轮换后返回结果。
它不需要任何下采样。</ p>
答案 2 :(得分:0)
当您的位图要大到要加载到内存中时抛出OutOfMemoryException。
我在这里给你一个解决方案。
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap preview_bitmap=BitmapFactory.decodeStream(is,null,options);
使用BitmapFactory.Options类的inSampleSize属性。
如果设置为值&gt;如图1所示,请求解码器对原始图像进行二次采样,返回较小的图像以节省存储器。样本大小是任一维度中对应于解码位图中的单个像素的像素数。例如,inSampleSize == 4返回的图像是原始宽度/高度的1/4,像素数量的1/16。任何值&lt; = 1都被视为1.注意:解码器使用基于2的幂的最终值,任何其他值将向下舍入到最接近的2的幂。
//decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f){
try {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
//The new size we want to scale to
final int REQUIRED_SIZE=70;
//Find the correct scale value. It should be the power of 2.
int scale=1;
while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
scale*=2;
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {}
return null;
}
答案 3 :(得分:0)
下面:
image = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), matrix, true);
代码运行两个位图,第一个image
是一个Bitmap
,你先前加载/解码到RAM中工作 - 实际旋转。第二个将由Bitmap.createBitmap()创建,无论您将结果存储到同一个变量中。无论如何,在这一行,你需要位图x2 RAM,这肯定会导致OOM(说到设备的最大可能照片)。
我认为使用NDK是最好的解决方案。
请检查my very same question here以获取其他可能的解决方案(MappedByteBuffer),它还包含指向NDK / JNI解决方案的链接。