旋转Android上的图像。有没有更好的办法?图像、办法、Android

2023-09-06 02:13:14 作者:捣蛋代言人

我有一个应用程序,为用户显示相当多的图片,我们已经看到了很多的错误报告与的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();
    }
  }