2010-01-11 4 views
13

Ich möchte Bilder mit DrawBitmap() -Methode zeigen. Aber bevor ich die Größe nach Bildschirmgröße ändern möchte. Ich habe ein Problem mit der Qualität des Ergebnisbildes. Sie können Screenshots und Testcode unten sehen. Wie kann ich Bilder in Runtime in guter Qualität skalieren?Android: Qualität der Bilder in Laufzeit geändert

Vielen Dank für die Lösungen.

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

Ergebnis Screenshot am Gerät: 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(); 
       } 
      } 
     }); 
    } 
} 

Antwort

10

Bitte beachten Sie Romain's answer unten.

Ich möchte diese Antwort löschen, aber ich kann nicht, da es als akzeptiert markiert ist.


Beachten Sie, dass Android [wenn diese Antwort wurde ursprünglich geschrieben, ohne 32-Bit-Farbe explizit anfordert] tun würde, nur 16-Bit-Farbe, so kann es vorkommen, dass Sie unerwünschte Artefakte zu bekommen.

Sie können auch versuchen, die Dither-Optionen zu verwenden, um Android anzuweisen, automatisch Dithering anzuwenden, was zwar nicht perfekt ist, aber die Dinge ein wenig besser aussehen lässt.

+1

Vielen Dank, es ist hilfreich Antwort! Aber ich habe keinen Ruf, um es zu wählen. – shinydev

+0

Jetzt verwende ich das "565 Dither Photoshop Plugin", um meine Grafik vorzubereiten. Da das Dithering ein High-Cost-Vorgang ist, funktioniert es nicht mit den Methoden decodeStream und drawBitmap. – shinydev

+1

Android kann 32 Bit gut machen. Stellen Sie nur sicher, dass sowohl Ihre Bitmap als auch Ihr Fenster das ARGB8888-Format verwenden. –

2

Check out http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html (Um mit unscaledBitmap = BitmapFactory.decodeStream (in) verwendet werden;

Sie kann dem Bild Qualitätseinstellungen hinzufügen Ich schätze, dass die Qualität verschlechtert wird, da Sie nicht ein y Einstellungen, wie das Bild verarbeitet werden soll.

+0

Was sind die "Qualitätseinstellungen" in "BitmapFactory.Options"? Ich kann keine sehen, und das Wort "Qualität" erscheint nicht einmal in der Dokumentation. –

+0

Es gibt http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inPreferQualityOverSpeed, aber die Dokumente sagen, es bezieht sich nur auf JPEG-Decodierung und Ihre Datei ist PNG. –

-1

Wenn die Größenänderungsfunktion das Seitenverhältnis des Bildes nicht berücksichtigt, wird die Qualität beeinträchtigt. Sie können einige Größenänderungsalgorithmen im Internet finden, zum Beispiel check this out

+0

Nein, beide Bilder haben das gleiche Verhältnis. Originalbild: 600x900 Ratio 1,5 neue Bildgröße: 320x480 Ratio 1,5 – shinydev

+0

Haben Sie keinen Größenänderungsalgorithmus bei der von Ihnen bereitgestellten Verbindung gefunden. Nur eine Diskussion über die korrekte Skalierung Berechnung ... – goRGon

15

Anstatt die Größe beim Zeichnen zu ändern (was sehr kostspielig sein wird), versuchen Sie, die Größe in einer Offscreen-Bitmap zu ändern und sicherzustellen, dass Bitmap 32 Bit (ARGB888) ist.

+0

Wie ich herausgefunden habe, wendet Android gute Downscaling-Algorithmus (nicht nächste Nachbar wie) nur bei der Verwendung von *** BitmapFactory.Options :: inSampleSize-> BitmapFactory.decodeResource() ** * Aber dies erlaubt, nur in genau ganzzahligen Zeiten kleiner als das Original zu verkleinern. Gibt es eine Möglichkeit, in Android auf eine genaue Auflösung zu reduzieren, die ich brauche etwas besser als Nächsten Nachbarn Algorithmus (der jedes Mal verwendet wird, wenn ich createScaledBitmap(), createBitmap + Matrix und e.t.c.)? – goRGon

1

Implementationen der createScaledBitmap (..) Methode auf älteren Plattformen (API-Ebene < 12) zu Problemen führen, wenn Sie versuchen, ein ARGB_8888 maßstab Bitmap, die keinen tatsächlichen Alpha-Wert hat (dh jedes Pixel hat Alpha = 255), weil ihr hasAlpha-Flag auf false gesetzt ist. In diesem Fall wird die skalierte Bitmap automatisch in das Format RGB_565 konvertiert.

daher seit API Level 12 gibt es ein Verfahren (in Bitmap-Klasse)

setHasAlpha(boolean value); 

, die eine Umwandlung zu verhindern hilft, wenn createScaledBitmap (..) verwendet wird.

Es gibt einen Weg, die gleiche Methode auf API-Ebene> 3 zu verwenden. Es ist seit sehr langer Zeit vorhanden, nur versteckt.Alle notwendigen Schritte, einschließlich des Quellcodes werden hier beschrieben:

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

Hoffnung, das hilft.