2010-01-11 18 views
13

Quiero mostrar imágenes usando el método drawBitmap(). Pero antes quiero cambiar el tamaño según las dimensiones de la pantalla. Tengo un problema con la calidad de la imagen del resultado. Puede ver capturas de pantalla y código de prueba a continuación. ¿Cómo puedo cambiar el tamaño de las imágenes en tiempo de ejecución con una buena calidad?android: calidad de las imágenes redimensionadas en tiempo de ejecución

Gracias por las soluciones.

imagen original: alt text http://dl.dropbox.com/u/709109/gradient.png

Resultado pantalla en el dispositivo: alt text http://dl.dropbox.com/u/709109/device.png

import android.app.Activity; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Rect; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.LinearLayout; 

import java.io.IOException; 
import java.io.InputStream; 

public class MyActivity extends Activity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     LinearLayout container = (LinearLayout) findViewById(R.id.container); 
     container.addView(new View(this) { 
      @Override 
      protected void onDraw(Canvas canvas) { 
       Bitmap unscaledBitmap; 
       try { 
        InputStream in = getAssets().open("images/gradient.png"); 
        unscaledBitmap = BitmapFactory.decodeStream(in); 
        in.close(); 
        canvas.drawBitmap(unscaledBitmap, null, new Rect(0, 0, 320, 480), null); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 
} 

Respuesta

10

Consulte Romain's answer a continuación.

Deseo eliminar esta respuesta, pero no puedo, ya que está marcada como aceptada.


Tenga en cuenta que Android [cuando esta respuesta fue escrito originalmente, sin solicitar explícitamente color de 32 bits] sólo lo haría color de 16 bits, lo que puede haber ocasiones en que reciba los artefactos no deseados.

También puede intentar usar las opciones de tramado para indicarle a Android que aplique automáticamente el tramado que, aunque no sea perfecto, puede ayudar a que las cosas se vean un poco mejor.

+1

¡Gracias, es una respuesta útil! Pero no tengo reputación de votarlo. – shinydev

+0

Ahora estoy usando el "565 dither photoshop plugin" para preparar mi gráfico. Porque el dithering es una operación de alto costo y no funciona con los métodos decodeStream y drawBitmap. – shinydev

+1

Android puede hacer 32 bits bien. Solo asegúrese de que tanto su mapa de bits como su ventana utilicen el formato ARGB8888. –

2

Salida http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html (Para ser utilizado con unscaledBitmap = BitmapFactory.decodeStream (en);

Usted puede agregar configuraciones de calidad a la imagen. Supongo que la calidad se está degradando ya que no está pasando un y la configuración de cómo debe procesarse la imagen.

+0

¿Cuáles son las "configuraciones de calidad" en 'BitmapFactory.Options'? No puedo ver ninguno, y la palabra "calidad" no aparece una vez en la documentación. –

+0

Hay http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inPreferQualityOverSpeed, pero los documentos dicen que solo se refiere a la decodificación JPEG y su archivo es PNG. –

-1

Además, si su función de cambio de tamaño no respeta la relación de aspecto de la imagen, la calidad se ve afectada. Puede encontrar algún algoritmo de cambio de tamaño en la web, por ejemplo check this out

+0

No, las dos imágenes tienen la misma proporción. imagen original: relación de 600x900 1.5 nuevo tamaño de imagen: relación 320x480 1.5 – shinydev

+0

No se encontró ningún algoritmo de cambio de tamaño en el enlace que proporcionó. Solo discusión sobre el cálculo del valor correcto de la escala ... – goRGon

15

En lugar de cambiar el tamaño en el tiempo de dibujo (que va a ser muy costoso), intente redimensionar en un mapa de bits fuera de pantalla y asegúrese de que Bitmap sea de 32 bits (ARGB888).

+0

Como descubrí, Android aplica un buen algoritmo de reducción de escala (no como el vecino más cercano) solo mientras usa *** BitmapFactory.Options :: inSampleSize-> BitmapFactory.decodeResource() ** * pero esto permite downscale solo en exactamente un número entero más pequeño que el original. ¿Hay alguna manera de reducir la escala en Android a una resolución exacta que necesito usar algo mejor que el algoritmo del vecino más cercano (que se usa cada vez que llamo a createScaledBitmap(), createBitmap + matrix y e.t.c.)? – goRGon

1

implementaciones del método createScaledBitmap (..) en las plataformas de mayor edad (nivel API < 12) causan problemas al intentar escalar un ARGB_8888 Mapa de bits que no tiene un valor alfa real (es decir, cada píxel tiene alfa = 255), porque su indicador hasAlpha se establece en falso. En ese caso, el mapa de bits escalado se convierte automáticamente al formato RGB_565.

tanto desde el nivel de la API 12 hay un método (en Bitmap clase)

setHasAlpha(boolean value); 

que ayuda a prevenir una conversión cuando se utiliza createScaledBitmap (..).

Hay una manera de utilizar el mismo método en el nivel de API> 3. Ha estado presente durante mucho tiempo, solo escondido.Se describen todas las medidas necesarias, incluyendo el código fuente aquí:

https://stackoverflow.com/a/12202069/1082933

Espero que esto ayude.

Cuestiones relacionadas