在android上旋转图像.有没有更好的办法?

Dra*_*ken 10 android out-of-memory android-imageview

我有一个应用程序,为用户显示了很多图像,我们已经看到很多错误报告,OutOfMemoryError但有例外.

我们目前的工作是:

// 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);
Run Code Online (Sandbox Code Playgroud)

显而易见的问题是我们必须从内存中的图像重新创建位图并旋转矩阵,这对于内存来说非常昂贵.

我的问题很简单:

是否有更好的方法来旋转图像而不会导致OutOfMemoryError

and*_*per 6

2种旋转大图像的方法:

  1. 使用JNI,就像这篇文章一样.

  2. 使用文件:这是一种非常慢的方式(取决于输入和设备,但仍然非常慢),它将解码后的旋转图像放入磁盘,而不是将其放入内存.

使用文件的代码如下:

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();
    }
  }
Run Code Online (Sandbox Code Playgroud)


Can*_*ner 0

你可以试试:

image.setImageBitmap(null);
// 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);
}
BitmapDrawable bd = new BitmapDrawable(mContext.getResources(), bmp);
bmp.recycle();
bmp = null;
setImageDrawable(bd);
bd = null;
Run Code Online (Sandbox Code Playgroud)