Swing Farbe aus Pixel vom JFrame auslesen

derSoerrn

Aktives Mitglied
Guten Tach,

ich probiere gerade ein wenig mit dem Zeichen in [JAPI]javax.swing[/JAPI] auf einem JPanel rum. Bekomme es mittlerweile auch hin eine Linie zu zeichnen, die sich mit der Tastatur steuern lässt. Allerdings würde mich interessieren, wie ich sicherstellen kann, dass die Linie nur dann gezeichnet wird, wenn der Untergrund z.B. schwarz ist --> also noch nicht vorher "bezeichnet" wurde.

Ich habe mir erst überlegt, alle Positionen der Linie in einer Liste zu speichern - hab diese Idee aber schnell wieder verworfen, da ich glaube, dass wenn man länger zeichnet die Liste viel zu lang wird und das Programm dann unnötig ausgebremst wird.

Die 2. Möglichkeit, die ich mir überlegte war mit der Klasse Robot ([JAPI]java.awt.Robot[/JAPI]) zu arbeiten. Allerdings hab ich keine Ahnung, wie ich sie benutzen soll. Ich hab bereits etwas rumprobiert und jeweils Positionen abgefragt, allerdings bekomme ich immer merkwürdige Farben, die überhaupt nicht auf meinem JFrame ([JAPI]javax.swing.JFrame[/JAPI]) sind, denn der Hintergrund ist schwarz und die Linie Rot...

Java:
colorXLeft = (int) (line.getXPos() + (line.width / 2) + (line.width / 2) * line.sin(angle)) + p.x;
colorYLeft = (int) (line.getYPos() + (line.height / 2) - (line.height / 2) * line.cos(angle)) + p.y;
colorXFront = (int) (line.getXPos() + (line.width / 2) + (line.width / 2) * line.cos(angle)) + p.x;
colorYFront = (int) (line.getYPos() + (line.height / 2) + (line.height / 2) * line.sin(angle)) + p.y;
colorXRight = (int) (line.getXPos() + (line.width / 2) - (line.width / 2) * line.sin(angle)) + p.x;
colorXLeft = (int) (line.getYPos() + (line.height / 2) + (line.height / 2) * line.cos(angle)) + p.y;
					
cBackLeft = robot.getPixelColor(colorXLeft, colorYLeft);
cBackRight = robot.getPixelColor(colorXRight, colorYRight);
cBackFront = robot.getPixelColor(colorXFront, colorYFront);

System.out.println("CBackLeft: " + cBackLeft.equals(cCompare) + ", denn Farbe: " + robot.getPixelColor(colorXLeft, colorYLeft));
System.out.println("Position-Robot: " + colorXLeft + ", " + colorYLeft);
System.out.println("CBackFront: " + cBackFront.equals(cCompare) + ", denn Farbe: " + robot.getPixelColor(colorXFront, colorYFront));
System.out.println("Position-Robot: " + colorXFront + ", " + colorYFront);
System.out.println("CBackRight: " + cBackRight.equals(cCompare) + ", denn Farbe: " + robot.getPixelColor(colorXRight, colorYRight));
System.out.println("Position-Robot: " + colorXRight + ", " + colorYRight);
if( !cBackLeft.equals(cCompare) || !cBackFront.equals(cCompare) || !cBackRight.equals(cCompare)){
	System.out.println("Vllt beim nächsten Mal ;-)");
}

Dieses
Code:
p.x
bzw.
Code:
p.y
am Ende der Zeilen gibt den wirklichen x bzw y Wert des JFrames auf dem Bildschirm zurück.

Hoffe Ihr könnt mir helfen
 
Zuletzt bearbeitet:
eine andere Möglichkeit, den robot zu benutzen ist, mithilfe von dem ein BufferedImage vom Screen zu erstellen.

Da kannst du dann mithilfe von getRGB() einfacher deine Farbwerte suchen

stackoverflow
 
Ne ich glaube, dass das nicht so gut wäre, da ich dann alle 20 ms ein neues BufferedImage erstellen würde und das denke ich ziemlich rechenaufwendig ist. Oder nicht?
 
So, da mir ja niemand antworten kann/will hab ich in der Zwischenzeit mal ein paar kleine Tests durchgeführt. Unter anderem hab ich mir mal grafisch zeigen lassen, an welcher Stelle der Robot die Farben ausliest. Ich hab' nen Screenshot gemacht und an diesen Text angefügt. Dort seht ihr 3 Quadrate (Hab die nur gemacht, weil ein einzelner Pixel schwerer zu erkennen gewesen wäre) und an der jeweils oberen linken Ecke wird die Farbe abgefragt. Habt ihr ne bessere Idee als sowas?
 

Anhänge

  • KOMPLETT DUMM.PNG
    KOMPLETT DUMM.PNG
    921 Bytes · Aufrufe: 30
Zuletzt bearbeitet:
Ist denn der gelbe Kreis auch an der Stelle (x|y), wo er gezeichnet wurde?

@keine Antwort: Auch ich unterliege höheren Mächten 😳

Gruß eMmiE
 
Erstmal: Das mit keine Antwort war mehr so allgemein auf die Leute im Forum bezogen.. 😛

Und ja wird er aber hab den Fehler so halb gefunden. Hab aus Versehen den Farbwert zum vergleichen auf grün gesetzt (wieso auch immer). Jedoch bin ich immer noch auf der Suche nach einer effizienteren Lösung als mit dem Robot
 
In nem anderen Forum hab ich einen gefunden, der zusätzlich noch nen GraphicsDevise eingebaut haut und dann danach den Robot mit
Code:
new Robot(devise)
initialisiert hat.
Ich weiß jetzt nicht, wies dann mit der Performance aussieht, er hat nicht mehr geantwortet...

Nur was zu deiner Beschäftigung 😀

Generell sind die Leute hier total lieb und so und sind generell hilfsbereit

Gruß eMmiE
 
Ich weiß, die helfen alle super. Nur ich liege leider gerade krank im Bett und denke den ganzen Tag schon drüber nach, was ich an dem Programm ändern könnte 😀

Kannst du mir den Link vom anderen Forum mal schicken?
 
Hmm.. da ja irgendwie niemand mehr schreibt frage ich nochmal neu:

Ich hab nen kleines Programm geschrieben in dem eine Linie gezeichnet wird, bei der ich nun überprüfen will, ob der Untergrund schwarz ist. Hier erstmal der Quellcode des Programms:

Java:
package bewegtesZeichnen;

import java.awt.AWTException;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.geom.Ellipse2D;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class XXX {

	public static void main(String[] args) {
		new XXX();
	}

	private JFrame window = new JFrame();
	private Curve curve, curve2;
	private Robot robot;

	private Thread animationThread;

	private Color cBackLeft = Color.BLACK, cBackFront = Color.BLACK, cBackRight = Color.BLACK;
	private Color cCompare = Color.BLACK;

	private Point p;

	private boolean playing = false;
	private boolean plus;
	private boolean minus;

	private float x = 300;
	private float y = 200;

	private int angle = 360;

	private int centerX, centerY;
	private int radius;

	private int colorXLeft, colorYLeft;
	private int colorXFront, colorYFront;
	private int colorXRight, colorYRight;
	
	private int colorXFrontRobot, colorYFrontRobot;
	private int colorXLeftRobot, colorYLeftRobot;
	private int colorXRightRobot, colorYRightRobot;

	public XXX() {
		window.setSize(1000, 800);
		window.setBackground(Color.BLACK);
		window.setLocationRelativeTo(null);
		window.setFocusable(true);
		window.requestFocus();
		load();

		try {
			robot = new Robot();
		} catch (AWTException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		p = window.getLocation();
		cCompare = window.getBackground();

		curve = new Curve();
		curve2 = new Curve();

		window.addKeyListener(curve);
		window.add(curve);
		window.requestFocus();
		
		JOptionPane.showMessageDialog(window, "LEERTASTE zum starten und DELETE zum beenden der Linie drücken");
		window.repaint();
	}

	private void load() {
		// windowlistener, um die noch laufenden Threads
		// beim schließen des Fensters zu beenden
		window.addWindowListener(new WindowListener() {

			@Override
			public void windowOpened(WindowEvent arg0) {
				// TODO Auto-generated method stub

			}

			@Override
			public void windowIconified(WindowEvent arg0) {
				// TODO Auto-generated method stub

			}

			@Override
			public void windowDeiconified(WindowEvent arg0) {
				// TODO Auto-generated method stub

			}

			@Override
			public void windowDeactivated(WindowEvent arg0) {
				// TODO Auto-generated method stub

			}

			@Override
			public void windowClosing(WindowEvent e) {
				// TODO Auto-generated method stub
				System.exit(0);
			}

			@Override
			public void windowClosed(WindowEvent arg0) {
				// TODO Auto-generated method stub
				System.exit(0);
			}

			@Override
			public void windowActivated(WindowEvent arg0) {
				// TODO Auto-generated method stub

			}
		});

		// Sichtbarkeit des Fensters
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				window.setVisible(true);
			}
		});

		// Thread um das Programm am Laufen zu halten:
		animationThread = new Thread(new Runnable() {
			public void run() {
				curve.positionCheck.start();
				curve.repaint();
				while (playing) {
					if (x < window.getWidth() - 30 && x > 0 && y > 0
							&& y < window.getHeight() - 30) {
						curve.repaint();
						if (plus) {
							if (angle < 360) {
								angle += 1;
							} else {
								angle = 0;
							}
						} else if (minus) {
							if (angle > 0) {
								angle -= 1;
							} else {
								angle = 360;
							}
						}
						try {
							Thread.sleep(10);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					window.requestFocus();
				}
			}
		});
		
	}

	private class Curve extends JPanel implements KeyListener {
		
		private Graphics2D g2d;
		
		private Thread positionCheck;
		
		private Color c = new Color(0, 200, 0, 200);
		private Color c2 = new Color(0, 0, 200, 180);
		private Color c3 = new Color(200, 0, 0, 180);

		private float height = 12f;
		private float width = 12f;

		public Curve() {
			this.setSize(1000, 800);
			this.setOpaque(true);
			this.setBackground(Color.BLACK);

			radius = (int) (height / 2);
			
			positionCheck = new Thread(new Runnable() {
				
				@Override
				public void run() {
					// TODO Auto-generated method stub
					while(playing){
						// Mittelpunkt des Kreises
						centerX = (int) (getPosX() + radius);
						centerY = (int) (getPosY() + radius);
						
						// Linker Punkt des Kreises
						colorXLeft = (int) (centerX + (radius * curve.sin(angle)));
						colorYLeft = (int) (centerY - (radius * curve.cos(angle)));
						
						// Vorderer Punkt des Kreises
						colorXFront = (int) (centerX + (radius * curve.cos(angle)));
						colorYFront = (int) (centerY + (radius * curve.sin(angle)));
						
						// Rechter Punkt des Kreises
						colorXRight = (int) (centerX - (radius * curve.sin(angle)));
						colorYRight = (int) (centerY + (radius * curve.cos(angle)));
						
						// Zum debuggen, da er mir zwischen ca 20° & 130° falsche Farben gibt
						colorXFrontRobot = (int) (centerX + ((radius + 5) * curve.cos(angle)));
						colorYFrontRobot = (int) (centerY + ((radius + 5) * curve.sin(angle)));
						
						colorXLeftRobot = (int) (centerX - ((radius + 5) * curve.sin(angle)));
						colorYLeftRobot = (int) (centerY + ((radius + 5) * curve.cos(angle)));
						
						colorXRightRobot = (int) (centerX - ((radius + 5) * curve.sin(angle)));
						colorYRightRobot = (int) (centerY + ((radius + 5) * curve.cos(angle)));
						
						cBackLeft = robot.getPixelColor(colorXLeftRobot + p.x, colorYLeftRobot + p.y);
						cBackFront = robot.getPixelColor(colorXFrontRobot + p.x, colorYFrontRobot + p.y);
						cBackRight = robot.getPixelColor(colorXRightRobot + p.x, colorYRightRobot + p.y);
						try {
							Thread.sleep(10);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			});
		}

		public void paintComponent(Graphics g) {
			// super.paintComponent(g);
			if (playing) {
				
				//Zum grafischen darstellen der Punkte die der Robot überprüft
				// g.setColor(c);
				// g.drawRect(colorXFrontRobot, colorYFrontRobot, 35, 35);
				//
				// g.setColor(c2);
				// g.drawRect(colorXLeftRobot, colorYLeftRobot, 35, 35);
				//
				// g.setColor(c3);
				// g.drawRect(colorXRightRobot, colorYRightRobot, 35, 35);
				
				if (isAlright(cBackLeft, cBackFront, cBackRight)) {
					g2d = (Graphics2D) g;
					g2d.setColor(Color.RED);
					g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,	RenderingHints.VALUE_ANTIALIAS_ON);
					Ellipse2D.Float sign1 = new Ellipse2D.Float(getPosX(), getPosY(), width, height);
					g2d.fill(sign1);
				} else {
//					System.out.println("X:       " + getPosX() + ", Y: "
//							+ getPosY());
//					System.out.println("Vorne X: " + colorXFront
//							+ ", Vorne Y: " + colorYFront);
//					System.out.println("Robot X: " + colorXFrontRobot
//							+ ", Robot Y: " + colorYFrontRobot);
//					System.out.println("Winkel:  " + angle);
//					System.out.println();
				}
			}
		}

		private boolean leftIsStillPressed = false;
		private boolean rightIsStillPressed = false;

		@Override
		public void keyPressed(KeyEvent e) {
			// TODO Auto-generated method stub
			if (e.getKeyChar() == 'a' || e.getKeyChar() == 'A'
					|| e.getKeyCode() == KeyEvent.VK_LEFT) {
				plus = false;
				minus = true;
				leftIsStillPressed = true;
			} else if (e.getKeyChar() == 'd' || e.getKeyChar() == 'D'
					|| e.getKeyCode() == KeyEvent.VK_RIGHT) {
				plus = true;
				minus = false;
				rightIsStillPressed = true;
			} else if (e.getKeyCode() == KeyEvent.VK_SPACE) {
				playing = true;
				animationThread.start();
			} else if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
				playing = false;
			}
		}

		@Override
		public void keyReleased(KeyEvent e) {
			// TODO Auto-generated method stub
			if (e.getKeyChar() == 'a' || e.getKeyChar() == 'A'
					|| e.getKeyChar() == KeyEvent.VK_LEFT) {
				minus = false;
				leftIsStillPressed = false;
				if (rightIsStillPressed) {
					plus = true;
				}
			} else if (e.getKeyChar() == 'd' || e.getKeyChar() == 'D'
					|| e.getKeyChar() == KeyEvent.VK_RIGHT) {
				plus = false;
				rightIsStillPressed = false;
				if (leftIsStillPressed) {
					minus = true;
				}
			}
		}

		@Override
		public void keyTyped(KeyEvent e) {

		}

		public float getPosX() {
			x = x + curve.cos(angle);
			return x;
		}

		public float getPosY() {
			y = y + curve.sin(angle);
			return y;
		}

		public float sin(int i) {
			if (i == 180 || i == 360) {
				return 0;
			} else {
				double intoRadians = Math.toRadians(i);
				float result = (float) Math.sin(intoRadians);
				return result;
			}
		}

		public float cos(int i) {
			if (i == 90 || i == 270) {
				return 0;
			} else {
				double intoRadians = Math.toRadians(i);
				float result = (float) Math.cos(intoRadians);
				return result;
			}
		}

		public boolean isAlright(Color colorLeft, Color colorFront,
				Color colorRight) {
			cCompare = Color.BLACK;
			if (colorLeft.equals(cCompare) && colorFront.equals(cCompare)
					&& colorRight.equals(cCompare)) {
				return true;
			} else if(!colorLeft.equals(cCompare)){
				System.out.println("Farbe links: " + colorLeft + ", Farbe zum Vergleichen: " + cCompare);
				System.out.println("X:       " + getPosX() + ", Y: " + getPosY());
				System.out.println("links X: " + colorXLeft + ", links Y: " + colorYLeft);
				System.out.println("Robot X: " + colorXLeftRobot + ", Robot Y: " + colorYLeftRobot);
				System.out.println("Winkel:  " + angle);
				System.out.println();
			} else if(!colorFront.equals(cCompare)){
				System.out.println("Farbe vorne: " + colorFront + ", Farbe zum Vergleichen: " + cCompare);
				System.out.println("X:       " + getPosX() + ", Y: " + getPosY());
				System.out.println("Vorne X: " + colorXFront + ", Vorne Y: " + colorYFront);
				System.out.println("Robot X: " + colorXFrontRobot + ", Robot Y: " + colorYFrontRobot);
				System.out.println("Winkel:  " + angle);
				System.out.println();
			} else if(!colorRight.equals(cCompare)){
				System.out.println("Farbe rechts: " + colorFront + ", Farbe zum Vergleichen: " + cCompare);
				System.out.println("X:       " + getPosX() + ", Y: " + getPosY());
				System.out.println("rechts X: " + colorXRight + ", rechts Y: " + colorYRight);
				System.out.println("Robot X: " + colorXRightRobot + ", Robot Y: " + colorYRightRobot);
				System.out.println("Winkel:  " + angle);
				System.out.println();
			}else{
//				System.out
//				.println("Clolor Left: " + colorLeft.equals(cCompare));
//		System.out.println(colorLeft);
//		System.out.println("Clolor Right: "
//				+ colorRight.equals(cCompare));
//		System.out.println(colorRight);
//		System.out.println("Clolor Front: "
//				+ colorFront.equals(cCompare));
//		System.out.println(colorFront);
//		System.out.println();
			}
			return false;
		}
	}
}

Hab, wie ihr sicher gemerkt habt, den Robot aus awt benutzt. Leider gibt er mir an der richtigen Stelle falsche Farben aus. Weiß jemand wieso?
 
Zuletzt bearbeitet:
Ich hab zwar keine Ahnung wieso, aber um das zu überprüfen, könntest du doch einfach ein farbiges Rechteck zeichnen lassen, nicht unbedingt bei (0,0), weiß nicht, bei (10,10), und dann einfach mal den Robot über das ganze Bild gehen lassen, von (0,0) an, bis er die Farbe erkannt hat. Dann vergleichst du die beiden Koordinaten und findest entweder seine Abweichung (hast du an die Insets vom Fenster gedacht?) oder ein neues spannendes Rätsel:lol:

Gruß eMmiE
 
Also ich weiß zwar nicht, ob ich das geprüft habe, was du meintest.. Aber der Robot liest in jedem Fall immer die richtigen Pixel aus. Hab nen kleines extra Programm geschrieben, indem er die Maus immer an die Stelle bewegt, an der er die Pixelfarbe ausliest und es klappte alles perfekt. Also keine Ahnung warum das bei der Linie, da, nicht funktioniert... Ziemlich mysteriös...

Wäre cool wenn Euch noch was einfallen würde, damit es klappt
 
Hast du die Insets beachtet?
Probier das Ganze mal mit JFrame:
Code:
setUndecorated(true)
Dann sollte es klappen...

Die Insets sind die lustigen, bei XP blauen, bei Windows 7 durchsichtigen Balken, die dein Fenster umrahmen.

Die links, rechts und unten, sind soweit ich weiß 2 Pixel breit, die Leiste oben irgendwas zwischen 32 und 27
 

Neue Themen


Zurück
Oben