如何在Java中绘制图像?

我使用JFrame导入并显示图像,并使用mousemotionlistener来检测鼠标点击,我希望能够在图像上绘制。 我想能够,如果用户点击,使该像素成为某种颜色,同时保留图像的其余部分,但是,我无法找到如何使用图形这样做而不删除图像的其余部分或者打开一个新窗口。

public class Simple extends JFrame{ static ImageIcon icon; static JFrame myframe; static JLabel mylabel; static BufferedImage image = null; public static void main(String[] args) { try{ image = ImageIO.read(new File("mypic.png")); } catch (IOException e) { e.printStackTrace(); } icon=new ImageIcon(image); myframe=new JFrame(); myframe.setSize(200,200); myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mylabel=new JLabel(); mylabel.setIcon(icon); myframe.getContentPane().add(mylabel); myframe.pack(); Container container = myframe.getContentPane(); MouseMotionEvents3 mousemotion = new MouseMotionEvents3(); container.add(mousemotion); myframe.setVisible(true); while(1 == 1) { if(mousemotion.signal == true) { System.out.println("second message"); mousemotion.signal = false; } } } } class MouseMotionEvents3 extends JPanel implements MouseListener, MouseMotionListener { public boolean signal; public MouseMotionEvents3() { addMouseListener(this); addMouseMotionListener(this); signal = false; } public void mouseClicked(MouseEvent me) { // System.out.println("i hate you"); } public void mouseEntered(MouseEvent me) { } public void mouseExited(MouseEvent me) { } public void mousePressed(MouseEvent me) { signal = true; System.out.println("message"); } public void mouseReleased(MouseEvent me) { } public void mouseDragged(MouseEvent me) { } public void mouseMoved(MouseEvent me) { } } 

我强烈建议您首先阅读“ 执行自定义绘画”和“ 2D图形轨迹” ,它们将为您提供一个起点。

您可以通过多种方式实现此目的,此示例只是跟踪点击点并在图像顶部绘制点

 import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class Test { public static void main(String[] args) { new Test(); } public Test() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { JFrame frame = new JFrame(); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private List points; private BufferedImage image; public TestPane() { points = new ArrayList<>(25); try { image = ImageIO.read(new File("/Users/shanewhitehead/Desktop/Screen Shot 2017-03-09 at 1.55.18 pm.png")); } catch (IOException ex) { ex.printStackTrace(); } addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { points.add(e.getPoint()); repaint(); } }); } @Override public Dimension getPreferredSize() { return image == null ? new Dimension(200, 200) : new Dimension(image.getWidth(), image.getHeight()); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); if (image != null) { g2d.drawImage(image, 0, 0, this); } g2d.setColor(Color.RED); for (Point p : points) { g2d.fillOval(px - 4, py - 4, 8, 8); } g2d.dispose(); } } } 

此示例直接将点绘制到图像本身…

 import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class Test { public static void main(String[] args) { new Test(); } public Test() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { JFrame frame = new JFrame(); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private BufferedImage image; public TestPane() { try { image = ImageIO.read(new File("/Users/shanewhitehead/Desktop/Screen Shot 2017-03-09 at 1.55.18 pm.png")); } catch (IOException ex) { ex.printStackTrace(); } addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (image != null) { Point p = e.getPoint(); Graphics2D g2d = image.createGraphics(); g2d.setColor(Color.RED); g2d.fillOval(px - 4, py - 4, 8, 8); g2d.dispose(); repaint(); } } }); } @Override public Dimension getPreferredSize() { return image == null ? new Dimension(200, 200) : new Dimension(image.getWidth(), image.getHeight()); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); g2d.drawImage(image, 0, 0, this); g2d.dispose(); } } } 

在这两种情况下,他们只是使用Graphics2D API

最简单的方法是获得一个代表你想要着色的像素的点列表。 然后覆盖标签的paint方法,首先调用super.paint (显示图像),然后绘制已单击的像素。

 List points = new ArrayList<>(); myLabel = new JLabel() { @Override public void paint(Graphics g) { super.paint(g); points.forEach(p -> g.fillRect(px, py, 1, 1)); } }; 

在鼠标处理中,只需将当前点添加到列表中并重新绘制标签。

 public void mouseClicked(MouseEvent me) { points.add(me.getPoint()); myLabel.repaint(); } 

有更复杂的方法涉及缓冲图像,但这可能足以让您入门。

我想通了,我可以使用JFrame的getGraphics()方法让自己在图像上绘制。

编辑:安德鲁汤普森是对的,最小化窗口删除更改。