Farblayer berechnen

Status
Nicht offen für weitere Antworten.

Clip

Bekanntes Mitglied
Hallo,

ich möchte über ein Bild einen Farblayer legen. Natrülich programmatisch, sonst würe ich auch in einem Photoshopforum fragen :)
Das ganze passiert in SWT. Das ist aber eigentlich egal, denn meine Frage ist SEHR grundsätzlicher Natur. Ich kann bereits auf jeden Pixel einer Grafik zugreifen, nur auch auch dessen rot, grüen und blau Wert richtig auszulesen funktioniert noch nciht so gut ...Am besten erstmal der bestehende Code:
Code:
	private void colorize() {
		ImageData ideaImageData = imageDesciptor.getImageData();
		
		// Die Layer Farbwerte (alles sollte ersteinmal beimalten bleiben)
		int redShift = 0;
		int greenShift = 0;
		int blueShift = 0;

		int[] lineData = new int[ideaImageData.width];
		for (int y = 0; y < ideaImageData.height; y++) {
			ideaImageData.getPixels(0, y, ideaImageData.width, lineData, 0);
			// Analyze each pixel value in the line
			for (int x = 0; x < lineData.length; x++) {
				// Extract the red, green and blue component
				int pixelValue = lineData[x];				
				int r = pixelValue & redShift;
				int g = (pixelValue & greenShift) >> 8;
				int b = (pixelValue & blueShift) >> 16;
				// weiß oder fast weiß auf ganz weiß setzen ;)
				if (r > 230 && g > 230 && b > 150) {
					ideaImageData.setPixel(x, y, 0xFFFFFF);
				} else {
//  ------------>                  hier soll der neue Wert hin
					ideaImageData.setPixel(x, y, ???);
				}
			}
		}
		// SWT ImageDescriptor erstellen
		Image image = new Image(null, ideaImageData);
		imageDesciptor = ImageDescriptor.createFromImage(image);
	}
Das Problem ist, dass der neu Berechnete Wert immer schwarz ist. (Ausser die Farbe ist fast oder ganz weiß, siehe Code)
Ich muss also wissen, wie ich einen Farbwert richtig auslesen , und im Anschluss den neu berechneten wieder einfügen kann.

Weiß jemand wie das geht?
Danke
 

Clip

Bekanntes Mitglied
Danke, es funktionier (fast) mit dem unteren Code. Leider geht das setzten der Farbe aber noch nicht s.u.
Code:
Code:
			for (int x = 0; x < lineData.length; x++) {
				// Extract the red, green and blue component
				int pixelValue = lineData[x];
				int r = (pixelValue >> 16) & 0xFF; 
				int g = (pixelValue  >> 8) & 0xFF; 
				int b = (pixelValue >> 0) & 0xFF; 
				//System.out.println(r + " " + g + " " + b);
				ideaImageData.setPixel(x, y, (((((b) >> 8) & g) >> 16) & r));
			}
Damit erhalte ich inwischen jeden Farbwert richtig. Zum Test möchte ich jetzt den Pixelfarbwert wieder aus r, g und b zusamensetzten um so das Bild in den originalen Farbwerten zu erhalten. Wenn das funktioniert, kann ich anfnagen die Farbwerte zu verändern. Leider funktioniert es aber noch nicht so ganz. Mit der '!tollen' (von mir anscheinend sinnfrei) ausgedachten Mehtode den Wert zu berechnen '(((((b) >> 8) & g) >> 16) & r)' bekomme ich aufjedenfall immer nur ein schwarz.... Da ich in Sachen bitweises und/oder noch ein Neuling bin habe ich nicht so den rechten Plan wie ich aus den drei Werten wieder einen Farbwert berechnen kann.
Weiß jemand wie das geht?
Danke!
 

The_S

Top Contributor
Code:
        rgb = ((a & 0xFF) << 24) |
               ((r & 0xFF) << 16) |
               ((g & 0xFF) << 8)  |
               ((b & 0xFF) << 0);
 

Clip

Bekanntes Mitglied
Super Danke!

Also mit SWT und ImageDesciptor s geht das so:
Code:
		public ImageDescriptor getColoredImageDescriptor() {
		
		Color maskColor = new Color(null, 219, 249,185);
		
		imageDesciptor = IconProvider.getImageDescriptor(image, imageSize);
		ImageData ideaImageData = imageDesciptor.getImageData();
		
		int mask_r = maskColor.getRed();
		int mask_g = maskColor.getGreen();
		int mask_b = maskColor.getBlue();


		int[] lineData = new int[ideaImageData.width];
		for (int y = 0; y < ideaImageData.height; y++) {
			ideaImageData.getPixels(0, y, ideaImageData.width, lineData, 0);
			// Analyze each pixel value in the line
			for (int x = 0; x < lineData.length; x++) {
				// Extract the red, green and blue component
				int pixelValue = lineData[x];
				//System.out.println("alt " + pixelValue);
				int r = (pixelValue >> 16) & 0xFF; 
				int g = (pixelValue  >> 8) & 0xFF; 
				int b = (pixelValue >> 0) & 0xFF; 
				
				// Neuer Farbwerte mit der Maske überlagern
				r = (r & mask_r);
				g = (g & mask_g);
				b = (b & mask_b);
				
				// neuen Farbwert berechnen
				int neu = ((r & 0xFF) << 16) 
							| ((g & 0xFF) << 8)  
							|((b & 0xFF) << 0);				
								
				//System.out.println("neu " + neu);
				ideaImageData.setPixel(x, y, neu);
			}
		}
		;
		maskColor.dispose();
		Image image = new Image(null, ideaImageData);
		imageDesciptor = ImageDescriptor.createFromImage(image);
		return imageDesciptor;
	}
 

Clip

Bekanntes Mitglied
Ich habe noch eine Frage. Wofür ist der Wert a in
Code:
((a & 0xFF) << 24)
??
 

Clip

Bekanntes Mitglied
Hm wofür bracht man denn das? (Sorry bin in Sachen Grafik nicht so bewandert).

Ich habe noch ein Problem beim addieren von Farbwerten. Nach dem ich mal mit exotischeren Farben getestet habe als (255,0,0), habe ich bemerkt, dass sich einige neu berechnete Farben recht eigenwillig verhalten. Teilweise "rutschen" sie krass in einen anderen Farbwert ab. Ich weiß auch nicht so genau wie ich das erklären soll :(

Ist an der Vorgehensweise:
Code:
				r = (r & mask_r);
				g = (g & mask_g);
				b = (b & mask_b);
etwas nicht vollständig oder falsch?
 

The_S

Top Contributor
1.) alpha = transparenz
2.) welche Werte haben den die jeweiligen "Masken"? Was möchtest du damit erreichen?
 

Clip

Bekanntes Mitglied
Es geht um folgende Anwendgung. Ich habe beliebige Icons als PNGs in meiner Anwendung. In Listen, Bäumen und Tabellen werden Daten durch diese Icons repräsentiert. Die Daten haben bestimmte Merkmale. Der Anwender soll beliebigen Merkmalen beliebige Farben zuordnen können. Aus diesem Grund möchte ich die vom Benutzer ausgewählten Farben auf die Icons anwenden. Dazu habe ich mir ein leicht graues, fast weisse Icon mit 3D Efeckt erstellt, und wende je nach Datenmerkmalen die vom Benuter definierten Farben auf das Icon an. Bildlich gesprochen genau das was passiert wennich mir eine farbige Sonnenbrille auf die Nase setzte :)
Alles funktioniert, nur leider werden die Farben bei bestimmten zu addierenden Farbwerten etwas komisch dargetsellt.... :autsch:
 

The_S

Top Contributor
Und warum wurstelst du dann mit nem AND-Vergleich in der Gegend rum?

Nur ein Beispiel:

00011101 = 1 + 4 + 8 + 16 = 29
00000111 = 1 + 2 + 4 = 7

00011101 & 00000111 = 00000101 = 1 + 4 = 5
29 + 7 = 36
 

Clip

Bekanntes Mitglied
Weil ich nicht weiss wie sonst gehen soll...
Addiere ich das ganze einfach, sehen die Farbverläufe zwar wieder gut aus, allerdings haben die Farben überhaupt nichts mehr mit denen zu tun die ich haben will (ping, rosa, orange etc).
 

The_S

Top Contributor
kommt halt darauf an wie genau der user die farbe einstellen kann. Wenn er 3 Slider hat für r, g und b, dann musst du halt daraus jeweils die neue Farbe berechnen, auch wenns scheiße aussieht. Muss du schon selber wissen, wie der User Farben manipulieren kann, und wie sich das Ganze dann auf dein Bild auswirkt
 

Clip

Bekanntes Mitglied
Ja, der User hat son ein typischen Farbdialog. Ob scheisse aussieht oder nicht ist mir egal. Das muss der User schon selber wissen. Mein Problem ist aktuell eher, dass ich die Farben nicht richtig berechne. Ich kenne keinen Algorythmus wie das zuverlässig zu bewerkstelligen wäre.
 

The_S

Top Contributor
tja und ich weiß nicht, WIE die Farben berechnet werden sollen. Also was du gegeben hast, wie sie verändert werden sollen, ...
 

Clip

Bekanntes Mitglied
Was ich berechnen möchte ist sozusagen ein "Sonnenbrillen" Efeckt. Also eine Farbe (z.B. 72, 215, 130 (ein Grünton)) flächendeckend über ein Grafik legen. Dabei soll die Grafik natürlich noch zu erkennen sein. Ich möchte also einen vorhandenen Pixel so berechnen, dass die Pixelfarbe und die Layerfarbe eine neue Farbe ergeben die entsprechend der physikalischen Gesetzte die 'richtige' ist.
 

The_S

Top Contributor
Spontan:

Du errechnest den Mittelwert aller 3 Farbkanäle eines Pixels. Somit kannste schonmal graustufen. Jetzt erhöhst bzw. verringerst du die Werte jedes Farbkanals relativ zu deiner gegebenen Wunschfarbe. Fertig.
 

Clip

Bekanntes Mitglied
Der Mittelwert scheint zu reichen:
Code:
				int pixelValue = lineData[x];
				int r = (pixelValue >> 16) & 0xFF;
				int g = (pixelValue >> 8) & 0xFF;
				int b = (pixelValue >> 0) & 0xFF;

				// Neuer Farbwerte mit der Maske überlagern (Mittelwert)							
				r = (r + mask_r) / 2;
				g = (g + mask_g) / 2;
				b = (b + mask_b) / 2;
				// neuen Farbwert berechnen
				int neu = ((r & 0xFF) << 16) | ((g & 0xFF) << 8)
						| ((b & 0xFF) << 0);

Vielen Dank!!!!!
 

Clip

Bekanntes Mitglied
Jetzt weiss ich was du mit "jetzt kannst du schon mal grau" meinst :)
Die von mir berechneten Farben sehen alle zwar eingefärbt, aber dennoch leicht grau aus.

Das mit dem relativen Verschieben des Farbwertes, wie von Dir geschrieben ,ist anscheinent für den letzten Pfif entscheident.

Aber wie kann ich den Wert verschieben? Angenommen ich will Rot und Blau vermischen.

Mit meinr Formel:
r(255) + r(0) / 2 = r(128)
g(0) + g(0) / 2 = g(0)
b(0) + b(255) = b(128)

Herauskommt ein dunkles Lila.

Eigentlich müsste es aber ein knall Lila (255,0,255) sein.

Was ich machen könnte, wäre auf den neu berechneten Wert noch mal den Layerfarbwert zu addieren, maximal jedoch bis 255. Allerdings, das ist reine Spekulation...

Code:
	            r = r + mask_r < 255 ? r + mask_r : 255;
	            g = g + mask_g < 255 ? g + mask_g : 255;
	            b = b + mask_b < 255 ? b + mask_b : 255;

Das Ergebnis sind deutlich knalligere Farben. Sie erscheinen eigentlich schon übertrieben...
Leider werde ich im Internet in Sachen korrekten Berechnung nich so recht fündig.. :(
 

The_S

Top Contributor
Nene, so hab ich das eigentlich auch gemeint ;) . Wenn du nunmal einen Ausgangswert von 0, 0, 0 also schwarz hast, dann kannste net erwarten, dass dabei leuchtende Farben rauskommen. Ich bin jetzt davon ausgegangen, dass du wirklich nur ein normales pic mit einer Farbe in verschiedenen hell- und dunkeltönen haben möchtest (die Variante mit dem mittel-Wert). Möchtest du aber die Originalfarben weitesgehend erhalten, dann addiere einfach den Originalfarbkanal mit dem entsprechenden der gewünschten Farbe und teile das Ergebnis dann durch 2. So haste du so nen "Ich schimmer in der und der Farbe, hab aber dennoch die Originalfarben"-Effekt ;) .

Eine weitere Alternative wäre, über das Bild einfach ein (zu einem bestimmten Anteil transparentes) Rechteck zu zeichnen. So kannst du die intensität deines "Sonnenbrillen-Effekts" sehr gut selbst regulieren.

Code:
		BufferedImage img = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_ARGB);
		Graphics2D g = img.createGraphics();
		g.drawImage(src, 0, 0, null);
		g.setColor(new Color(col.getRed(), col.getGreen(), col.getBlue(), 100));
		g.fillRect(0, 0, img.getWidth(), img.getHeight());
		g.dispose();

Aber vorsicht, ein Image mit transparenz, kann auch nur in ein Grafikformat, das Transparenz unterstützt gespeichert werden (z. B. .png).
 

The_S

Top Contributor
Hm, Farbwertberechnung ist logisches denken, aus dem RGB int die Alpha, Red, Green und Blue werte auslesen und wieder zusammensetzen ist Source-Code der Klasse "Color" anschauen, Transparentes Rechteck über das Bild legen ist API-Kenntnis (bzw. 2,5 Jahre Java-Erfahrung).

:p
 

Clip

Bekanntes Mitglied
Ich habe mir jetzt eine Methode 'reColorize' geschrieben.
Code:
	// hier werden die Farben nochmal nachberechnet um sie 'knalliger' zu machen 
	private static int reColorize(int orgColor, int layerColor ,int averageColor){
		int color = averageColor;
		int div = 5;
		
		if (layerColor > orgColor) color +=  ((layerColor - orgColor)  / div);
		if (layerColor < orgColor) color -=  ((orgColor - layerColor )  / div);
		
		color = color < 255 ? color : 255;
		color = color > 0  ? color : 0; 
				
		return color;		
	}

Diese benötigt die Originalkanalfarbe eines Pixels, die Layerkanalfarbe und den bereits berechneten Mittelwert.
Anhand des Teilers 'div' kann der Kontrast eingestellt werden. Je höher der Wert, desto näher liegt das Ergebis an dem bereits berechneten Mittelwert. Bei dem Wert 1 ist das Ergebnis sehr knallig :) Für meine Zwecke ist der Wert 5 ein guter! Die Farben erscheinen hell und leuchtend, das Originalbild hinter dem Layer ist ebenfalls noch gut zu erkennen.

Die Methode sollte noch vernünftig in das Gesamtfarbberechnungskonzept eingebunden werden, ansonsten ist sie OK.

Vielen Dank für die Hilfe!
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
Tippster JavaFX Scene neu berechnen lassen AWT, Swing, JavaFX & SWT 5
W JavaFX Button - optimale Breite berechnen AWT, Swing, JavaFX & SWT 1
Z Swing Kann man denn abstand zwischen zwei Buttons berechnen AWT, Swing, JavaFX & SWT 5
Neumi5694 Größe von Komboboxen neu berechnen AWT, Swing, JavaFX & SWT 3
A Swing JFrame neuzeichnen lassen, position neu berechnen lassen? AWT, Swing, JavaFX & SWT 9
M JavaFX Image View Würfel berechnen AWT, Swing, JavaFX & SWT 3
F Schriftgröße von Buchstaben berechnen AWT, Swing, JavaFX & SWT 3
B 2D-Grafik Collision berechnen AWT, Swing, JavaFX & SWT 2
H preferred size abhängig von Fenstergröße berechnen AWT, Swing, JavaFX & SWT 11
S Farbverlauf in for-Schleife berechnen AWT, Swing, JavaFX & SWT 4
M Swing JTextField "onthefly" auslesen und berechnen AWT, Swing, JavaFX & SWT 7
D Swing JViewPort, Absolut Koordinaten berechnen. AWT, Swing, JavaFX & SWT 2
A AWT HSB-Farben dynamisch berechnen AWT, Swing, JavaFX & SWT 5
T Swing JEditorPane Groesse berechnen AWT, Swing, JavaFX & SWT 2
C Alternative zu getFontMetrics um Stringlänge zu berechnen AWT, Swing, JavaFX & SWT 2
Schandro Den größten passenden java.awt.Font zu einem Rectangle berechnen AWT, Swing, JavaFX & SWT 2
M Animation berechnen AWT, Swing, JavaFX & SWT 4
D Koordinaten von einem Kreissegment berechnen AWT, Swing, JavaFX & SWT 6
T Breite des Containers ist gegeben - wie die Höhe berechnen? AWT, Swing, JavaFX & SWT 3
J Schriftgröße aus vorhandenem Platz berechnen AWT, Swing, JavaFX & SWT 9
J resize eines Bildes automatisch berechnen lassen? AWT, Swing, JavaFX & SWT 2
G winkel berechnen AWT, Swing, JavaFX & SWT 4
P Winkel berechnen AWT, Swing, JavaFX & SWT 18

Ähnliche Java Themen

Neue Themen


Oben