繁体   English   中英

如何在Java中绘制图像?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM