Java机器人类-获取像素颜色后';重画
我需要为我的小ms paint应用程序创建一个颜色选择器工具。 我最初问如何从图形2D实现切换到图形2D-->BuffereImage实现(然后很容易获得像素),但有人建议我在robot类中获得像素颜色 首先,这是我的MCEVE:NB。它不能是一个类,它不会保存Java机器人类-获取像素颜色后';重画,java,swing,graphics,rgb,awtrobot,Java,Swing,Graphics,Rgb,Awtrobot,我需要为我的小ms paint应用程序创建一个颜色选择器工具。 我最初问如何从图形2D实现切换到图形2D-->BuffereImage实现(然后很容易获得像素),但有人建议我在robot类中获得像素颜色 首先,这是我的MCEVE:NB。它不能是一个类,它不会保存 import java.awt.*; import javax.swing.*; public class Runner { public static void main(String[] args){ JFrame M
import java.awt.*;
import javax.swing.*;
public class Runner {
public static void main(String[] args){
JFrame Maiframe = new JFrame("Paint");
Canvas DrawingBoard = new Canvas();
Maiframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Maiframe.setSize(700, 500);
Maiframe.add(DrawingBoard);
Maiframe.setVisible(true);
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
public class Canvas extends JPanel {
public int xp; //present x
public int yp; //present y
public int xo; //old x
public int yo; //old y (Drawing from starting to new point as mouse drags)
public Canvas(){
super();
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
xo = e.getX();
yo = e.getY();
Color col = RGBFinder();
System.out.println("RGB : Red =" + col.getRed() + "Green" + col.getGreen() + "Blue" + col.getRed());
}
});
addMouseMotionListener(new MouseMotionAdapter() { //get coords as mouse drags
@Override
public void mouseDragged(MouseEvent e) {
xp = e.getX();
yp = e.getY();
if(SwingUtilities.isLeftMouseButton(e))
repaint(); //call paintcomponent
}
public void mouseMoved(MouseEvent e1){ //keep trak of coords when mouse is not dragging
xo = e1.getX();
yo = e1.getY();
}
});
}
public void draw(int x, int y, Graphics g){ //draw the line
if(xo != 0)
g.drawLine(xo, yo, x, y);
xo = x; //old x is now present x and so on
yo = y;
}
public void paintComponent(Graphics g){
super.paintComponent(g);
draw(xp, yp, g);
}
}
public Color RGBFinder(){
try{
robot = new Robot();
}
catch(AWTException e){
System.out.println("Could not create color picker robot");
}
PointerInfo pi = MouseInfo.getPointerInfo();
Point p = pi.getLocation();
Color pixelColor = robot.getPixelColor(p.x, p.y);
//also tried robot.getPixelColor(p.getX(), p.getY());
//also tried to pass coordinates from listener to RGBFinder, and use those, no luck. (event.getX() ...)
return pixelColor;
}
而且效果很好
我需要实现一些东西,当鼠标点击时,从任何像素获取颜色
我这样做了:(将此方法添加到画布,并从鼠标单击器侦听器调用它)
呼叫示例:
//replace old mouseListener with this
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
xo = e.getX();
yo = e.getY();
Color col = RGBFinder();
System.out.println(" da tela Red =" + col.getRed() + "Green" + col.getGreen() + "Blue" + col.getRed());
}
});
不幸的是,从这个实现中,我得到了未定义的行为。颜色读数始终为255、255、255。如果我给洞面板上色,那么它10次中有9次是正确的,但在某些区域它仍然没有
我还尝试过用robot#screenCap将整个过程包装到一个BuffereImage中,但这甚至无法远程工作
我做错了什么
多谢各位
编辑1:
有人怀疑在第二条线被画出来后,一条线如何能留在屏幕上。我将提供一个屏幕截图:
NBB。这是因为Canvas的实例是在JFrame内部创建为Runnable的,所以更改被保存,从而避免了对形状和ArrayList的需要
我还将添加一个完整版本的代码,该代码打印错误的RGB结果,请记住,这不会按原样保存行。请参考以上两个单独的类别进行测试
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
public class Canvas extends JPanel{
public int xp; //present x
public int yp; //present y
public int xo; //old x
public int yo; //old y (Drawing from starting to new point as mouse drags)
public Robot robot;
public static void main(String[] args){
JFrame Maiframe = new JFrame("Paint");
Canvas DrawingBoard = new Canvas();
Maiframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Maiframe.setSize(700, 500);
Maiframe.add(DrawingBoard);
Maiframe.setVisible(true);
}
public Canvas(){
super();
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
xo = e.getX();
yo = e.getY();
Color col = RGBFinder();
System.out.println("RGB --> Red =" + col.getRed() + "Green" + col.getGreen() + "Blue" + col.getRed());
}
});
addMouseMotionListener(new MouseMotionAdapter() { //get coords as mouse drags
@Override
public void mouseDragged(MouseEvent e) {
xp = e.getX();
yp = e.getY();
if(SwingUtilities.isLeftMouseButton(e))
repaint(); //call paintcomponent
}
public void mouseMoved(MouseEvent e1){ //keep trak of coords when mouse is not dragging
xo = e1.getX();
yo = e1.getY();
}
});
}
public void draw(int x, int y, Graphics g){ //draw the line
if(xo != 0)
g.drawLine(xo, yo, x, y);
xo = x; //old x is now present x and so on
yo = y;
}
public void paintComponent(Graphics g){
super.paintComponent(g);
draw(xp, yp, g);
}
public Color RGBFinder(){
try{
robot = new Robot();
}
catch(AWTException e){
System.out.println("Could not create color picker robot");
}
PointerInfo pi = MouseInfo.getPointerInfo();
Point p = pi.getLocation();
Color pixelColor = robot.getPixelColor(p.x, p.y);
//also tried robot.getPixelColor(p.getX(), p.getY());
//also tried to pass coordinates from listener to RGBFinder, and use those, no luck. (event.getX() ...)
return pixelColor;
}
}
我的小ms绘画应用程序
嗯,这不是一个绘画应用程序。它所做的只是画一条线。无论何时尝试绘制第二条线,第一条线都将被删除
因此,你需要做的第一步是决定你希望这幅画如何工作。有两种常见的方法:
ArrayList
中,然后paintComponent(…)
方法将绘制列表中的每个对象缓冲区图像
,然后绘制组件(…)
方法可以只绘制缓冲区图像
Draw-on-Component
方法,则可以使用MouseInfo
和Robot
获得像素颜色:
PointerInfo pi = MouseInfo.getPointerInfo();
Point p = pi.getLocation();
System.out.println( robot.getPixelColor(p.x, p.y) );
如果使用在图像上绘制
方法,则可以从缓冲区图像
获取像素颜色:
int rgb = bufferedImage.getRGB(mouseEvent.getX(), mouseEvent.getY());
Color color = new Color( rgb );
System.out.println( color );
最终更新
您仍然没有发布SSCCE。你发布的代码没有划清界限。即使它确实画了一条线,你希望我们如何(精确地)点击一条像素线
SSCCE的目的是演示您所询问的概念。您正在询问如何获取面板上像素的颜色。绘图如何进入面板与问题无关,因此绘制代码应尽可能简单
以下是正确的SSCCE。注:
createAndShowGUI()
和main()
方法对于所有SSCCE都是相同的。区别在于“DrawingPanel代码/类”将更改以演示您的问题import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DrawingCanvas extends JPanel
{
private Robot robot;
public DrawingCanvas()
{
addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
try
{
robot = new Robot();
}
catch(Exception re) { System.out.println(re); }
PointerInfo pi = MouseInfo.getPointerInfo();
Point p = pi.getLocation();
Color pixelColor = robot.getPixelColor(p.x, p.y);
System.out.println(pixelColor);
}
});
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor( Color.RED );
g.fillRect(0, 0, 40, 40);
g.setColor( Color.GREEN );
g.fillRect(40, 40, 40, 40);
g.setColor( Color.BLUE );
g.fillRect(80, 80, 40, 40);
}
private static void createAndShowGUI()
{
JPanel panel = new DrawingCanvas();
JFrame frame = new JFrame("DrawingCanvas");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setSize(200, 200);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater( () -> createAndShowGUI() ); // Java 8 only
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
}
只要复制/粘贴/编译/执行代码就可以了
我会让你弄明白为什么你的代码看起来不起作用
NBB。这是因为Canvas的实例是在JFrame内部创建为Runnable的,所以更改被保存,从而避免了对形状和ArrayList的需要
这种说法是完全错误的。在paintComponent()方法中使用图形对象完成的绘制只是临时的,直到下次调用paintComponent()方法为止
例如,在frame.setVisible()语句之后添加以下代码:
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Graphics g = panel.getGraphics();
g.setColor( Color.YELLOW );
g.fillRect(120, 120, 40, 40);
}
});
调整帧大小时,黄色方形将消失。对于永久性绘画,你需要使用我在原始答案中建议的两种方法之一
编辑2:
这是我分别单击红色、绿色、蓝色和背景时得到的输出:
C:\Java>java DrawingCanvas
java.awt.Color[r=255,g=0,b=0]
java.awt.Color[r=0,g=255,b=0]
java.awt.Color[r=0,g=0,b=255]
java.awt.Color[r=238,g=238,b=238]
我删除了
robot
标记,因为您谈论的是一些Java类而不是物理机器人:)除此之外,您是否检查了发送给robot
的正确坐标?您是否检查了PointerInfo
使用的坐标系?如果您使用了错误的坐标系,您的位置可能在画布/面板之外,因此返回了错误的值。是的,我有。坐标是正确的。非常感谢您的阅读和帮助。变量名不应该以大写字母开头。不要称你的班级为“画布”。这是一个AWT类名,令人困惑。使用更好的描述性类名。首先,这是我的MCVE:
-这不是MCVE。代码应该在一个类文件中,我们可以复制/粘贴/编译/执行。我的类名不是Canvas,我从意大利语翻译了代码以使其不可理解,这是我发现的最接近的东西。很抱歉,这是我能到达的最接近MCVE的地方,我还不知道如何将所有内容放在同一个类中,请创建单独的
C:\Java>java DrawingCanvas
java.awt.Color[r=255,g=0,b=0]
java.awt.Color[r=0,g=255,b=0]
java.awt.Color[r=0,g=0,b=255]
java.awt.Color[r=238,g=238,b=238]