我有一个应用程序,为用户显示相当多的图片,我们已经看到了很多的错误报告与的OutOfMemoryError
例外。
I have an app that displays quite a few images for the user, and we've been seeing a lot of error reports with OutOfMemoryError
exception.
我们现在做的是这样的:
What we currently do is this:
// Check if image is a landscape image
if (bmp.getWidth() > bmp.getHeight()) {
// Rotate it to show as a landscape
Matrix m = image.getImageMatrix();
m.postRotate(90);
bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), m, true);
}
image.setImageBitmap(bmp);
与此明显的问题是,我们必须重新从存储器中的图像的位图和旋转矩阵,这对于内存相当昂贵的。
The obvious problem with this is that we have to recreate the bitmap from the image on memory and rotate the matrix, this is quite expensive for the memory.
我的问题很简单:
有没有更好的办法,而不会造成旋转图像的OutOfMemoryError
?
Is there a better way to rotate images without causing OutOfMemoryError
?
旋转大图像的2种方法:
2 methods of rotating a large image:
使用JNI,如对这个职位。
使用一个文件:这是一个非常缓慢的方式(取决于输入和设备,但仍然很慢),这使代替把球送入德$ C $光盘旋转图像插入到磁盘第一,内存。
using a file : it's a very slow way (depending on the input and the device , but still very slow) , which puts the decoded rotated image into the disk first , instead of putting it into the memory .
$ C $使用文件c是如下:
code of using a file is below:
private void rotateCw90Degrees()
{
Bitmap bitmap=BitmapFactory.decodeResource(getResources(),INPUT_IMAGE_RES_ID);
// 12 => 7531
// 34 => 8642
// 56 =>
// 78 =>
final int height=bitmap.getHeight();
final int width=bitmap.getWidth();
try
{
final DataOutputStream outputStream=new DataOutputStream(new BufferedOutputStream(openFileOutput(ROTATED_IMAGE_FILENAME,Context.MODE_PRIVATE)));
for(int x=0;x<width;++x)
for(int y=height-1;y>=0;--y)
{
final int pixel=bitmap.getPixel(x,y);
outputStream.writeInt(pixel);
}
outputStream.flush();
outputStream.close();
bitmap.recycle();
final int newWidth=height;
final int newHeight=width;
bitmap=Bitmap.createBitmap(newWidth,newHeight,bitmap.getConfig());
final DataInputStream inputStream=new DataInputStream(new BufferedInputStream(openFileInput(ROTATED_IMAGE_FILENAME)));
for(int y=0;y<newHeight;++y)
for(int x=0;x<newWidth;++x)
{
final int pixel=inputStream.readInt();
bitmap.setPixel(x,y,pixel);
}
inputStream.close();
new File(getFilesDir(),ROTATED_IMAGE_FILENAME).delete();
saveBitmapToFile(bitmap); //for checking the output
}
catch(final IOException e)
{
e.printStackTrace();
}
}