【发布时间】:2016-06-28 13:56:33
【问题描述】:
我需要为我的小 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。如果我为孔板着色,那么 10 次中有 9 次正确,但在某些区域仍然丢失。
我也尝试过使用 robot#screenCap 将整个内容包装到 bufferedImage 中,但这甚至无法远程工作。
我在这里做错了什么?
非常感谢。
编辑1:
在绘制第二条线后如何在屏幕上保留一条线存在疑问。我会提供截图:
NBB。之所以可行,是因为 Canvas 的实例是在 JFrame 内部创建到 Runnable 中的,因此可以保存更改,从而避免了对形状和数组列表的需要。
我还将添加打印错误 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;
}
}
【问题讨论】:
-
我删除了
robot标签,因为你在谈论一些Java 类而不是物理机器人:) 除此之外,你是否检查了正确的坐标被发送到robot?您是否检查过PointerInfo使用的是哪个坐标系?如果您使用了错误的坐标系,您的位置可能在画布/面板之外,从而返回错误的值。 -
是的,我有。坐标是正确的。非常感谢您的阅读和帮助。
-
变量名不应以大写字符开头。不要称你为“画布”类。这是一个 AWT 类名,令人困惑。使用更好的描述性类名。
-
First of all, here's my MCVE:- 这不是 MCVE。代码应该在一个类文件中,我们可以复制/粘贴/编译/执行。 -
我的班级名称不是 Canvas,我从意大利语翻译了代码以使其难以理解,这是我找到的最接近的东西。很抱歉,这已经离 MCVE 很近了,我还不具备将所有内容放在同一个类中的知识,如果你有时间,请创建单独的文件。无论如何,非常感谢您的帮助。
标签: java swing graphics rgb awtrobot