Rotar imágenes en android. ¿Hay una mejor manera?

Tengo una aplicación que muestra unas pocas imágenes para el usuario, y hemos estado viendo una gran cantidad de informes de errores con la excepción OutOfMemoryError .

Lo que hacemos actualmente es el siguiente:

 // 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); 

El problema obvio con esto es que tenemos que recrear el mapa de bits de la imagen en la memoria y girar la matriz, esto es bastante caro para la memoria.

Mi pregunta es simple:

¿Hay una mejor manera de girar imágenes sin causar OutOfMemoryError ?

2 métodos de rotación de una imagen grande:

  1. Utilizando JNI, como en este post .

  2. Utilizando un archivo: es muy lento (dependiendo de la entrada y el dispositivo, pero aún muy lento), que pone la imagen girada descodificada en el disco primero, en lugar de ponerlo en la memoria.

El código de uso de un archivo es el siguiente:

 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(); } } 

puedes probar:

 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; 

Cuando trabaje con muchos mapas de bits, asegúrese de llamar a recycle () en ellos tan pronto como no se necesiten. Esta llamada liberará instantáneamente memoria asociada con un mapa de bits particular.

En su caso, si no necesita el mapa de bits original después de la rotación, recíclelo. Algo en la línea de:

 Bitmap result = bmp; // 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); result = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), m, true); // rotating done, original not needed => recycle() bmp.recycle(); } image.setImageBitmap(result); 
  • La dimensión de la pantalla del dispositivo tiene un efecto extraño en las imágenes a escala
  • ImageView en ListView que amplía el ancho máximo
  • Android cambia la imagen de fondo con la animación de entrada / salida
  • Haz que la imagen aparezca en la mitad de la pantalla
  • Cómo ampliar una vista de texto en android?
  • Tiempo de aumento de OnLongPress
  • ImageView src con el selector extraíble ignora el estado habilitado
  • Cómo crear una imageView con parámetros id y src?
  • ImageView no conserva la imagen cuando ocurre la rotación de la pantalla
  • Android - Vista de imagen en el centro en toda la resolución de la pantalla
  • Cómo crear el efecto de pulso ImageView con nueve animaciones androides de edad
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.