2012-07-29 11 views
13

¿Cómo obtengo un mapa de bits con un cierto tamaño (compatible con la memoria) de la cámara?Tamaño del mapa de bits devuelto por la cámara a través de intento?

estoy empezando una cámara con la intención:

Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
cameraIntent.putExtra("return-data", true); 

photoUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "mytmpimg.jpg")); 
cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, photoUri);   

startActivityForResult(cameraIntent, REQUEST_CODE_CAMERA); 

manejo el resultado aquí:

// Bitmap photo = (Bitmap) intent.getExtras().get("data"); 

Bitmap photo = getBitmap(photoUri); 

Ahora si uso la línea comentada - obtener el mapa de bits directamente, consigo siempre una 160 x 120 mapa de bits, y eso es demasiado pequeño. Si lo cargo desde el URI usando algunas cosas estándar que encontré (método getBitmap), carga un mapa de bits de 2560 x 1920 (!) Y eso consume casi 20 mb de memoria.

¿Cómo cargo, digamos 480 x 800 (el mismo tamaño que la vista previa de la cámara me muestra)?

Sin tener que cargar el 2560 x 1920 en la memoria y reducir la escala.

+0

¿Esto ayuda? http://stackoverflow.com/questions/3331527/android-resize-a-large-bitmap-file-to-scaled-output-file –

+0

Probablemente, pero ¿no hay una manera de obtener lo que veo en la pantalla? cuando tomas la foto ...? No necesito nada más. – Ixx

+0

El enlace de Ben Rujil apunta a la mejor respuesta que conozco. Su elección es básicamente una miniatura en Intent o una foto de resolución nativa en Archivo. La opción de que la aplicación de la cámara no se guarde para guardarla con una resolución más baja no está disponible. – Sparky

Respuesta

2

Esto es lo que se me ocurrió, basado en un método llamado getBitmap() de una biblioteca de cultivos que se eliminó de la versión anterior de Android. Hice algunas modificaciones:

private Bitmap getBitmap(Uri uri, int width, int height) { 
    InputStream in = null; 
    try { 
     int IMAGE_MAX_SIZE = Math.max(width, height); 
     in = getContentResolver().openInputStream(uri); 

     //Decode image size 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 

     BitmapFactory.decodeStream(in, null, o); 
     in.close(); 

     int scale = 1; 
     if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) { 
      scale = (int)Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE/(double) Math.max(o.outHeight, o.outWidth))/Math.log(0.5))); 
     } 

     //adjust sample size such that the image is bigger than the result 
     scale -= 1; 

     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize = scale; 
     in = getContentResolver().openInputStream(uri); 
     Bitmap b = BitmapFactory.decodeStream(in, null, o2); 
     in.close(); 

     //scale bitmap to desired size 
     Bitmap scaledBitmap = Bitmap.createScaledBitmap(b, width, height, false); 

     //free memory 
     b.recycle(); 

     return scaledBitmap; 

    } catch (FileNotFoundException e) { 
    } catch (IOException e) { 
    } 
    return null; 
} 

Lo que esto hace es cargar el mapa de bits utilizando BitmapFactory.Options() + algunos tamaño de la muestra - de esta manera la imagen original no se carga en memoria. El problema es que el tamaño de muestra simplemente funciona en pasos. Obtengo el tamaño de muestra "mínimo" para mi imagen usando algunas matemáticas que copié, y restamos 1 para obtener el tamaño de muestra que producirá el valor mínimo. mapa de bits más grande que el tamaño que necesito.

Y luego, para obtener el mapa de bits con exactamente el tamaño solicitado haga una escala normal con Bitmap.createScaledBitmap(b, width, height, false);. E inmediatamente después de reciclar el mapa de bits más grande. Esto es importante, porque, por ejemplo, en mi caso, para obtener un mapa de bits de 480 x 800, el mapa de bits más grande era 1280 x 960 y ocupaba una memoria de 4,6 mb.

Una manera más amigable con la memoria sería no ajustar scale, por lo que un mapa de bits más pequeño se ampliará para que coincida con el tamaño requerido. Pero esto reducirá la calidad de la imagen.

Cuestiones relacionadas