2009-11-24 12 views
18

Was wäre der richtige Weg, um eine Farbe Drawable in eine Graustufen zu verwandeln (um den deaktivierten Zustand anzuzeigen)?Drawable => Graustufen

EDIT:
B/W => Graustufen-

Antwort

91

Ich weiß, diese Frage vor einer Weile gefragt wurde, aber ich über eine einfachere Lösung kam, die, wenn Sie einen Auslosungs arbeitet und Sie wollen einfach nur das gleiche ziehbar anzuzeigen in Graustufen. Keine Notwendigkeit, eine Leinwand oder einen Maler zu haben ...

protected Drawable convertToGrayscale(Drawable drawable) 
{ 
    ColorMatrix matrix = new ColorMatrix(); 
    matrix.setSaturation(0); 

    ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix); 

    drawable.setColorFilter(filter); 

    return drawable; 
} 

Hoffe das hilft auch!

+0

wow, so einfach, so toll! – tacone

+0

Mann, du bist ein Zauberer, danke ein Brötchen! – Sipty

+1

Guter Tipp! Etwas Interessantes ist, dass Sie diese Methode ausführen, indem Sie ContextCompat.getDrawable übergeben (context, R.drawable.myId); Wenn Sie das nächste Mal dasselbe Zeichenfeld benötigen, ist der Farbfilter bereits eingestellt. Für meinen Teil muss ich den Farbfilter entfernen, um die Farbe wieder auf meinen Drawable zu bekommen :) – Tobliug

17

Anscheinend können Sie die ColorMatrix-Klasse verwenden, um jede Art von Farbraumtransformationen zu tun. Es hat eine setSaturation() Methode, die leicht eine Farb-Graustufen-Transformation (Nullsättigung) für Sie erstellt.

So können Sie diesen Filter verwenden, um eine neue Kopie des Bildes zu malen. Ich habe nicht versucht, aber es sollte funktionieren:

Bitmap grayscaleBitmap = Bitmap.createBitmap(
    colorBitmap.getWidth(), colorBitmap.getHeight(), 
    Bitmap.Config.RGB_565); 

Canvas c = new Canvas(grayscaleBitmap); 
Paint p = new Paint(); 
ColorMatrix cm = new ColorMatrix(); 

cm.setSaturation(0); 
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(cm); 
p.setColorFilter(filter); 
c.drawBitmap(colorBitmap, 0, 0, p); 
1

Sind Sie wollen speziell diese programmatisch zu tun und nicht nur mit behinderten Versionen der Bilder? Sie könnten auf ein XML-Zeichen verweisen, etwa:

+0

Ja, ich möchte es auf Instanzbasis tun. Danke für das Snippet. – yanchenko

3

Einige Kommentare zur Antwort von @intgr.
1. Bitmap.Config.ARGB_8888 um den Alpha-Kanal zu erhalten.
2. Ein wenig mehr Code:

//remember, you are converting a .png image, as opposed to a Drawable defined in .xml 
Bitmap colorBitmap = ((BitmapDrawable)drawable).getBitmap();  
// the code by intgr 
Drawable grayscaleDrawable = new BitmapDrawable(grayscaleBitmap); 
+1

Kleine Tippfehler: Bitmap.Config.RGB_8888 sollte Bitmap.Config.ARGB_8888 sein. Funktioniert gut, danke. – Minsky