2011-01-28 18 views
20

Gracias a Schermvlieger por preguntar this pregunta sobre anddev.org,uso óptimo de BitmapFactory.Options.inSampleSize para la velocidad

sólo estoy copiando a su pregunta de manera que nadie respondió en el otro sitio y también estoy enfrentando el mismo problema.

Me preguntaba cuál sería el uso óptimo de BitmapFactory.Options.inSampleSize con respecto a la velocidad de visualización de la imagen.
La documentación menciona el uso de valores que son una potencia de 2, por lo que estoy trabajando con 2, 4, 8, 16, etc.

Las cosas que me gustaría saber son:

  1. ¿Debo aplicar un nuevo muestreo hacia abajo al tamaño más pequeño que sigue siendo más grande que la resolución de la pantalla, o debería muestrear al tamaño suficiente para evitar un OutOfMemoryError?
  2. ¿Cómo se calcularía el tamaño máximo de una imagen que aún podría mostrarse sin quedarse sin memoria? ¿La profundidad de color de la imagen también juega un rol y la profundidad de la pantalla?
  3. Es eficiente para mostrar imágenes a través de dos mecanismos (BitmapFactory para archivos de gran tamaño, setImageURI() para los más pequeños) Estoy usando un ImageSwitcher por cierto.
  4. ¿Ayudaría crear el Bitmap, BitmapFactory.Options y inTempStorage al principio de la aplicación o crearlos solo sobre la marcha, cuando sea necesario?

Respuesta

11

Siempre debe intentar cargar y escalar previamente las imágenes para que estén lo más cerca posible de su tamaño visualizado final. Escalar imágenes en el momento del dibujo es extremadamente costoso y debe evitarse a toda costa.

Teniendo en cuenta el costo de la memoria de una imagen, sí, el color-deptch juega un papel muy importante. Las imágenes en formato ALPHA_8 usan 1 byte por píxel, las imágenes en RGB_565 o ARGB_4444 usan 2 bytes por píxel y las imágenes en ARGB_8888 usan 4 bytes por píxel. La profundidad de la pantalla no importa en absoluto. Siempre debe intentar usar ARGB_8888 para obtener la mejor calidad posible, pero 565 puede ser lo suficientemente bueno si su imagen es opaca.

+0

Cuando dice que "escalar imágenes en el momento del dibujo es extremadamente caro", ¿esto incluye options.inSampleSize también? – kape123

+0

inSampleSize se usa para escalar imágenes en tiempo de carga, no en tiempo de dibujado. Es una muy buena forma de preseleccionar imágenes. –

+1

Estamos usando ARGB_8888, que está produciendo una imagen muy borrosa en Samsung Galaxy Note 2, pero funcionó bien en otro dispositivo, actívelo ARGB_4444 está bloqueando la aplicación en Samsung Galaxy Note 2 y Pad 3110, debido a outOfMemoryError. ¿Puedes ayudarnos a resolver esto? –

3

Aquí puede llamar al método definido por el usuario shrinkmehtod que en realidad envía la ruta del archivo de cadena y el alto y el ancho para reducir la imagen al método.

Bitmap bit=shrinkmethod(arrpath1[position], 100, 100); 


      //iv.setImageURI(Uri.parse(arrpath1[position])); 
      iv.setImageBitmap(bit); 

Este es un método definido por el usuario para reducir el tamaño de la imagen mediante programación.

Bitmap shrinkmethod(String file,int width,int height){ 
     BitmapFactory.Options bitopt=new BitmapFactory.Options(); 
     bitopt.inJustDecodeBounds=true; 
     Bitmap bit=BitmapFactory.decodeFile(file, bitopt); 

     int h=(int) Math.ceil(bitopt.outHeight/(float)height); 
     int w=(int) Math.ceil(bitopt.outWidth/(float)width); 

     if(h>1 || w>1){ 
      if(h>w){ 
       bitopt.inSampleSize=h; 

      }else{ 
       bitopt.inSampleSize=w; 
      } 
     } 
     bitopt.inJustDecodeBounds=false; 
     bit=BitmapFactory.decodeFile(file, bitopt); 



     return bit; 

    } 

Espero que esto le ayude a reducir el tamaño.

+2

Orginalmente desde aquí http://madhusudhanrc.blogspot.fr/2012/09/reduce-bitmap-size-using.html – Snicolas

4

Ha hecho buenas preguntas, pero todo depende de sus necesidades y de cuánta memoria use. Recomiendo consultar este enlace para obtener muchos consejos sobre mapas de bits: http://developer.android.com/training/displaying-bitmaps/index.html.

En resumen, debe considerar el almacenamiento en caché, la disminución de resolución y el uso de un formato de mapa de bits lo suficientemente bueno siempre que pueda.

aquí está mi respuesta a sus preguntas:

  1. no

    Por qué tanto? si crees que puede haber OOM, trata de reciclar bitmaps viejos y sin usar y luego vuelve a verificar.

  2. se puede calcular el (estimado) tamaño del mapa de bits:

    ancho * alto * bytesPerPixel

    donde bytesPerPixel suele ser 4 ó 2 (dependiendo del formato de mapa de bits).

  3. Nunca utilicé setImageURI, así que no puedo ayudarte con eso. Sugiero descargar imágenes en un hilo de fondo (usar asyncTask es una forma de hacerlo) y mostrarlas cuando esté listo.

  4. Si solo hay unas pocas que sabe que no requerirán mucha memoria, creo que está bien. Todavía creo que el almacenamiento en caché podría ser mejor.

Cuestiones relacionadas