Memoria insuficiente al crear mapas de bits en el dispositivo

Estoy teniendo problemas con imágenes de alta resolución.

Estoy usando la carpeta nodpi-drawable para imágenes de 1280×720 y usando este código para escalarlo.

public static Drawable scaleDrawable(Drawable d, int width, Activity cxt) { BitmapDrawable bd = (BitmapDrawable)d; double oldWidth = bd.getBitmap().getWidth(); double scaleFactor = width / oldWidth; int newHeight = (int) (d.getIntrinsicHeight() * scaleFactor); int newWidth = (int) (oldWidth * scaleFactor); Drawable drawable = new BitmapDrawable(cxt.getResources(),MainScreen.getResizedBitmap(bd.getBitmap(),newHeight,newWidth)); BitmapDrawable bd2 = (BitmapDrawable)drawable; return drawable; } public static Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) { int width = bm.getWidth(); int height = bm.getHeight(); float scaleWidth = ((float) newWidth) / width; float scaleHeight = ((float) newHeight) / height; // create a matrix for the manipulation Matrix matrix = new Matrix(); // resize the bit map matrix.postScale(scaleWidth, scaleHeight); // recreate the new Bitmap Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false); return resizedBitmap; } 

Utilizo ese código para escalar imágenes a la pantalla, por lo que si la pantalla es 320×480, la imagen se escalará a 320 y mantendrá las proporciones, no me importa si la imagen sale de la pantalla desde abajo.

Todo funciona bien, pero al probar en un dispositivo xhdpi específicamente un Samsung Galaxy Note 2 con una pantalla de exactamente 720×1280.

Se bloquea con Out of Memory Exception en la línea:

 Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false); 

No puedo entender por qué, la imagen debe escalarse de 720 a 720, pero mi código debe estar realmente mal optimizado o algo así.

No he probado un dispositivo 1080×1920, pero parece que se bloqueará también.

¿Alguien puede ver algo malo cuando mira el código?

utiliza este método para cambiar el tamaño de tu bitmap

  Bitmap bm=decodeSampledBitmapFromPath(src, reqWidth, reqHeight); 

usa esta definición

  public Bitmap decodeSampledBitmapFromPath(String path, int reqWidth, int reqHeight) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; Bitmap bmp = BitmapFactory.decodeFile(path, options); return bmp; } } public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { if (width > height) { inSampleSize = Math.round((float) height / (float) reqHeight); } else { inSampleSize = Math.round((float) width / (float) reqWidth); } } return inSampleSize; } 

Si está utilizando un recurso, reemplace el método con el método decodeResource de BitmapFactory.

  public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { .... ..... return BitmapFactory.decodeResource(res, resId, options); } 

Debería usar la clase de utilidad BitmapFactory para las operaciones de procesamiento de imagen. También use BitmapFactory.Options para ajustar los tamaños de entrada / salida de los mapas de bits. Después de que ya no se necesita un bitmap, debe liberar la memoria relacionada.