[英]How to draw on top of an image in 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<Point> 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(p.x - 4, p.y - 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(p.x - 4, p.y - 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<Point> points = new ArrayList<>();
myLabel = new JLabel() {
@Override
public void paint(Graphics g) {
super.paint(g);
points.forEach(p -> g.fillRect(p.x, p.y, 1, 1));
}
};
在鼠标处理中,只需将当前点添加到列表中并重新绘制标签即可。
public void mouseClicked(MouseEvent me) {
points.add(me.getPoint());
myLabel.repaint();
}
有一些涉及缓冲图像的更复杂的方法,但这可能足以使您入门。
我弄清楚了,我可以使用JFrame的getGraphics()方法来允许自己在图像上方绘制。
编辑:安德鲁·汤普森(Andrew Thompson)是对的,最小化窗口会删除更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.