# Bild von RGB in Grayscale konvertieren



## grayson (30. Jun 2004)

hallo !

ich nutze Jsane-net um von einem scanner unter linux seiten zu scannen.

jsane liefert in jedem fall, egal welcher scanmodus genutzt wird 4 bit RGB bilder.

diese sollen in meinem programm in tiff konvertiert und in einer db abgelegt werden.

für twain funzt das schon ganz gut, hier liefert twain auch nicht immer rgb, will heissen : scanne ich dort in grayscale, bekomme ich auch grayscale und nicht RGB das so aussieht als ob 

unter twain haben meine konvertierten .tif bilder dann auch nur 25 k in dem dreh bei grayscale scannen.

mit jsane komme ich auf ca 500 k was mir viel zu viel ist.

daher also die schlussfolgerung :

wenn ich in grayscale scanne und 4 bit rgb zurück bekomme, ok dann muss ich es vor der tiff konvertierung erst noch in "richtiges" grayscale portieren.

und genau da ist mein problem !

ich hab keinen schimmer wie das geht bzw. die gängigen beispiele im netz, bekomme ich nicht zum laufen, da diese alle von 8 bit rgb ausgehen.... oder so... irgendwie...



hat jemand eine lösung / idee?

danke


----------



## Thorsten Sommer (2. Jul 2004)

Okay, dass ist kein Problem 

Zunächst musst du den RGB Wert für jeden Pixel auslesen. Das geht mit dem BufferedImage.
Ein leeres BufferedImage erzuegen, dann den Grafik Kontext besorgen, dann dein Bild hinein
zeichnen. Wenn ichmich jetzt nicht irre.

Danach musst du den RGB Wert in R, G und B teilen. Dafür hat Java die Klasse Color, wenn
ich mich nicht irre. Die hat einen Nachteil: Man braucht viele viele Instanzen von ihr. Daher
würde ich den original Sun Java Code aus der Klasse kopieren, und eine eigene Klasse
dafür schreiben, die mit einer Instanz auskommt. 

Wie auch immer  8) Nun musst du die R, G und B Werte addieren und durch drei Teilen,
dann hat man den Grauwert:

Grau = (R + B + G) / 3;

So ... und den kannst du dann in ein leeres Grauwert-Bild schreiben. Kannst du wohl
auch mit BufferedImage machen ... hab jetzt aber nicht nachgesehen, hab da nur so
was im Kopf  :wink: 

Mein Vorschlag für eine bessere "Color" Klasse:


```
public class RGBColor
{
	
   //Hier wird der 24 Bit RGB Wert gespeichert.
   private int Farbe;
	
   public RGBColor()
   {
   }

   public void setColor(int RGB)
   {
      Farbe = RGB;
   }

   public int getRed()
   {
      return (Farbe >> 16) & 0xFF;
   }

   public int getGreen()
   {
      return (Farbe >> 8) & 0xFF;
   }

   public int getBlue()
   {
      return (Farbe >> 0) & 0xFF;
   }

   public void setRGB(int R, int G, int B)
   {
      Farbe = ((255 & 0xFF) << 24) | ((R & 0xFF) << 16) | ((G & 0xFF) << 8)  | ((B & 0xFF) << 0);
   }

   public int getRGB()
   {
      return Farbe;
   }	
}
```

Einfach eine Instanz erzeugen, und entweder einen RGB Wert schreiben ( setColor() ) und
die R, G und G Werte lesen ( getRed(), getGreen(), getBlue() ), oder anders herum indem
du aus den R, G und B Werten einen RGB Wert machst ( setRGB() und getRGB() ).

Viel Spaß damit


----------



## Thorsten Sommer (2. Jul 2004)

PS: Mir ist noch eine Verbesserung eingefallen:   

Wenn dein Quellbild eh schon Grau ist, nur eben als RGB, dann kann man das auch alles sehr
kurz machen. Ist aber nur eine Theorie, die auch nicht stimmen kann!

Also ein Grau Bild als RGB müsste eigendlich als R, G und B Wert immer den selben Wert
haben. Daher ist die ganze Umwandlung RGB -> R,G,B -> Grau sinnlos. Dann genügt es,
wenn du nur den Rot Wert ließt, und diesen Wert direkt in das Zielbild schreibst, in das
Graubild.

Weil die Rechnung eh das Selbe ergibt.

Beispiel:
R = 10
G = 10
B = 10

Grau = (R + G + B) / 3 = (10 + 10 + 10) / 3 = 10

Alles klar?  8) Ist halt nur die Frage, ob das stimmt. Sind die drei Werte in einem RGB Bild mit
einem Grauwert Bild als Inhalt wirklich alle gleich? Muss man halt testen...


----------

