gpt4 book ai didi

Java 机器人类 - 在绘制后获取像素颜色

转载 作者:行者123 更新时间:2023-12-02 12:58:48 24 4
gpt4 key购买 nike

我需要为我的小 MS 绘画应用程序创建一个 colorPicker 工具。我最初询问如何从 Graphics 2D 实现切换到 Graphics2D-->BufferedImage 实现(然后很容易获取像素),但有人建议我通过机器人类获取像素颜色。

首先,这是我的 MCEVE:注意。它不能是单个类,它不会保存。

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;

}

而且效果很好。

我需要实现一些东西,以便在单击鼠标时从任何像素获取颜色。

我这样做了:(将此方法添加到 Canvas,并从鼠标点击器监听器调用它)

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。除非我给孔面板着色,那么十次中有九次都是正确的,但在某些区域仍然缺少它。

我还尝试使用 robots#screenCap 将整个内容包装到 bufferedImage 中,但这甚至无法远程工作。

我在这里做错了什么?

非常感谢。

编辑1:

人们对绘制第二条线后如何将一条线保留在屏幕上存在疑问。我将提供屏幕截图:

Several separated lines. I used a bigger brush size for visibility

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;

}
}

最佳答案

my little ms paint app

嗯,它并不是一个绘画应用程序。它所做的只是画一条线。每当您尝试绘制第二条线时,第一条线都会被删除。

因此,您需要做的第一步是决定绘画的效果。有两种常见的方法:

  1. 将要绘制的对象存储在 ArrayList 中,然后 paintComponent(...) 方法将绘制列表中的每个对象。

  2. 直接绘制到 BufferedImage,然后 paintComponent(...) 方法就可以绘制 BufferedImage

查看Custom Painting Approaches了解这两种方法的工作示例,并给出使用每种方法的优缺点。

I have instead been suggested to get the pixel colors thought the robot class

这取决于您想要使用哪种绘画方法。

如果您使用在组件上绘制方法,那么您将使用MouseInfoRobot来获取像素颜色:

PointerInfo pi = MouseInfo.getPointerInfo();
Point p = pi.getLocation();
System.out.println( robot.getPixelColor(p.x, p.y) );

如果您使用在图像上绘制方法,那么您将从BufferedImage获取像素颜色:

int rgb = bufferedImage.getRGB(mouseEvent.getX(), mouseEvent.getY());
Color color = new Color( rgb );
System.out.println( color );

最终更新

您还没有发布 SSCCE。您发布的代码不会画线。即使它确实画了一条线,您如何期望我们(准确地)单击单个像素线。

SSCCE 的目的是演示您所询问的概念。您询问如何获取面板上像素的颜色。绘图如何在面板上与问题无关,因此绘图代码应该尽可能简单。

以下是正确的 SSCCE。注:

  1. 对于所有 SSCCE,createAndShowGUI()main() 方法都是相同的。不同之处在于“DrawingPanel 代码/类将发生变化以演示您的问题。

  2. 自定义绘画是硬编码的。不需要您尝试解决的 mouseMoved/mouseDragged 逻辑(除非这是问题)。您所关心的只是点击不同的颜色。

  3. 只需使用简单的 System.out.println(...) 即可显示 Color 对象的值。

我所做的只是从类中复制相关的代码,并删除不相关的代码,以保持代码简单直接。任何人都可以做到。

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. This works because an instance of Canvas is create inside of a JFrame into Runnable, so the changes are saved, avoiding the need for shapes and arrayLists.

这种说法是完全错误的。在paintComponent() 方法中使用Graphics 对象完成的绘制只是暂时的,直到下次调用paintComponent() 方法为止。

例如在frame.setVisible()语句后添加以下代码:

SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Graphics g = panel.getGraphics();
g.setColor( Color.YELLOW );
g.fillRect(120, 120, 40, 40);
}
});

当调整框架大小时,黄色方 block 将会消失。对于永久性绘画,您需要使用我在原始答案中建议的两种方法之一。

编辑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]

关于Java 机器人类 - 在绘制后获取像素颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38078244/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com