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:
- Animar la imagen .png en el widget
- Android: establece un borde alrededor de un ImageView
- ImageView.getWidth () devuelve 0
- Recortar imagen a cuadrado - Android
- Personalizable con ImageView
// 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
?
- Cómo agregar mediante programación ImageView en LinearLayout sin espacios adicionales?
- Android: Uso del selector para establecer el color de fondo para la vista de imagen
- Cómo hacer un ImageView con esquinas redondeadas?
- Cómo cargar un ImageView con un archivo png sin usar "setImageBitmap ()"?
- Cómo detener otras imágenes para moverse mientras arrastra una imagen
- Anchura máxima y altura para ImageView en Android
- Calidad de mapa de bits Horrible ImageView?
- Animación de una imagen con ImageView
2 métodos de rotación de una imagen grande:
-
Utilizando JNI, como en este post .
-
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);
- ¿Debemos usar el proveedor de seguridad de google con OkHttp?
- No se puede initilizar la biblioteca de renderizado de OpenGL