# getRGB liefert andere Werte als PS?



## Fabse (30. Nov 2012)

Hi,

ich möchte gerne von jedem Pixel eines Bildes den RGB Wert auslesen. Leider macht Java das aber bissl anders, wenn ich das hier richtig verstehe [Java] RGB Werte korrekt auslesen (Solved)

In Photoshop kann man sich ja schön mit der Pipette jedes einzelne Pixel anzeigen lassen z.B.
0,255,0 wäre ein "richtiges" grün. Gibts eine Java-Methode die genau das kann? getRGB gibt einen int wert zurück, der wenn man ihn in ein Color Objekt schiebt nicht mit dem aus PS übereinstimmt 

Am Liebsten wäre mir eine Methode die mir 3 ints zurückgibt, also nen arry wo der erste Wert Red, der zweite Green und der dritte Blue wäre.

Gibts da was?

Danke.


----------



## trääät (1. Dez 2012)

grundsätzlich kommt es auf das format des bildes an was getRGB() liefert ...
das kann nämlich entweder ARGB bzw BGRA sein .. oder eine völlig andere codierung ...

da aber in der regel ARGB zurückgegeben wird kannst du doch einfach mit shift-ops die werte rausholen

int argb=getRGB();
int b=argb&0xFF;
int g=(argb>>8)&0xFF;
int r=(argb>>16)&0xFF;
int a=(argb>>24)&0xFF;

gibt dir dann blau, grün, rot und alpha im bereich 0 ... 255 ...

also braucht man keine methode die einem 4 ints zwischen 0 und 255 liefert sondern kann diese 4 jeweils 8 bit auch zusammen in einen 32bit int packen ... der rest ist lediglich geshifte sowie masking ...

wie gesagt : was dann in den einzelnen werten drin steht hängt von der codireung des images ab ...


----------



## trääät (1. Dez 2012)

btw .. hab das verlinkte erst nach meinem post gelesen ... dort steht eigentlich schon alles ...

was aber halt nicht genannt wurde was ich oben schon geschrieben habe : ES KOMMT AUF DEN TYP DES IMAGES AN ... entsprechend natürlich auch der return von getRGB()


----------



## Bernd Hohmann (1. Dez 2012)

Fabse hat gesagt.:


> In Photoshop kann man sich ja schön mit der Pipette jedes einzelne Pixel anzeigen lassen z.B.
> 0,255,0 wäre ein "richtiges" grün. Gibts eine Java-Methode die genau das kann? getRGB gibt einen int wert zurück, der wenn man ihn in ein Color Objekt schiebt nicht mit dem aus PS übereinstimmt
> 
> Am Liebsten wäre mir eine Methode die mir 3 ints zurückgibt, also nen arry wo der erste Wert Red, der zweite Green und der dritte Blue wäre.



Im RGB-Objekt kannst Du direkt .red .green .blue etc.. auslesen:


```
PaletteData pal = imgdPicture.palette;
	int pixel = imgdPicture.getPixel(x, y);
	RGB rgb = pal.getRGB(pixel);
	intVAL[rgb.red][RED]++;
	intVAL[rgb.green][GREEN]++;
	intVAL[rgb.blue][BLUE]++;
```

(aus einer Histogrammroutine rauskopiert).

Nur: die konkrete Farbe eines Pixels bei JPEG ist immer Ansichtssache (weil JPEG "Farbenblind" ist). Insbesondere wenn höherwertige Bildbearbeitungssoftware im Spiel ist kann da der Teufel was passieren. Wegen besserer Kompressionsmöglichkeiten wird auch gerne RGB in einen "luminance/chrominance color space" umgewandelt der dann bei der Dekomprimierung wieder nach RGB umgerechnet wird - oder auch nicht, wenn die Bildbearbeitungssoftware das nativ weiterverarbeiten kann. Oder die Pipette hebt nicht auf RGB Rohdaten sondern auf die bereits Farbkorrigierte Bildschirmdarstellung ab.

In der Praxis hab ich im Detail Abweichungen von über 60% in einzelnen RGB-Mischungen erlebt, heute mach ich mir da kaum noch einen Kopp drum.

Bernd


----------



## Spacerat (1. Dez 2012)

Ganz banal, ohne viel Gerechne, könnte hier die Info fehlen, dass der Alpha-Kanal (Transparenz) erstens immer dabei und zweitens "invertiert" ist. Ein 100% sichtbares Grün hätte demnach wider Erwarten den Wert 0xFF00FF00 statt 0x0000FF00. Das ist auch unabhängig vom BI-Typ (jedenfalls kommen da immer ARGB-Werte, auch bei monochromen Bildern). Dein Array bekommst du, wenn du trääts Berechnungen schlicht in ein [c]int[] {r, g, b}[/c] oder [c]int[] {r, g, b, a}[/c] packst.


----------



## trääät (1. Dez 2012)

ich versteh bloß irgendwie immer noch nicht warum getRGB() irgendwas anderes liefern sollte als nun mal die "echten" farb-werte ...

getRGB() liefert grundsätzlich ARGB nach dem was ich oben geschrieben habe ... und zwar schon nach dem java intern beim einlesen all die korrekturen an z.b. JPEG vorgenommen oder aus einer GIF-farbpalette wieder die richtigen werte berechnet hat ...

wenn du also ein grünes bild hast bei dem dir photoshop FF00FF00 liefert wird java das ganz sicher auch tun ... zur not kann man sich ja mal mit dem jpeg2000 algorithmus befassen ...


----------



## Spacerat (1. Dez 2012)

[OT]





trääät hat gesagt.:


> ...und zwar schon nach dem java intern beim einlesen all die korrekturen an z.b. JPEG vorgenommen oder aus einer GIF-farbpalette wieder die richtigen werte berechnet hat ...


Das macht er nicht schon beim Einlesen des Bildes, sondern erst beim "Abholen" der Werte mittels Color- und SampleModel. Nur so als Info.[/OT]


trääät hat gesagt.:


> wenn du also ein grünes bild hast bei dem dir photoshop FF00FF00 liefert wird java das ganz sicher auch tun ... zur not kann man sich ja mal mit dem jpeg2000 algorithmus befassen ...


...das ist genau das, was ich meinte. Evtl. liefert PS ja 0x0000FF00, bzw. ist das CM des BI ein RGB-Colormodel. Bei diesem wird der Alpha-Kanal stets auf 0xFF gesetzt, selbst wenn man nur RGB-Werte (also "100% transparente" Farben) im Bild setzt.


----------



## Spacerat (1. Dez 2012)

Ganz nebenbei fällt mir dazu auch noch ein... PS zeigt dir standardmässig grundsätzlich die RGB(A)-Werte der Layer an, unabhängig davon, in welchem Format du rausspeicherst. Erst wenn du das Gespeicherte erneut in PS einlädtst, siehst du die "echten" RGB(A)-Werte des Bildes, wie sie auch Java sieht. Dafür gab' es auch eine Prewiew-Funktion in PS, ich weis nur im Mom weder wie die hiess noch wo man sie findet.


----------



## Fabse (2. Dez 2012)

Hey,

Danke für die vielen Infos! Problem war, dass ich es als .jpg abgespeichert habe, wenn ich es als .png abspeichere liefert Java die gleichen Werte wie Photoshop


----------

