How to draw on top of an image in Java?

余生颓废 提交于 2019-12-02 08:51:41

I would highly recommend that you start by having a read through Performing Custom Painting and the 2D Graphics Trail, they will provide you with a starting point.

There are a number of ways you might achieve this, this example simply keeps track of the click points and draws dots over the top of the image

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();
        }

    }

}

This example draws the dots directly to the image itself...

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();
        }

    }

}

In both cases, they simply make use of the Graphics2D API

The simplest method would be to have a list of points that represent the pixels you wish to colour. Then override the paint method for the label to first call super.paint (to display the image) and then paint the pixels that have been clicked.

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));
    }
};

In your mouse handling just add the current point to the list and repaint the label.

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

There are more sophisticated methods that involve buffered images but this is likely good enough to get you started.

I figured it out, I can use the getGraphics() method of the JFrame to allow myself to draw on top of the image.

edit: Andrew Thompson is right, minimizing the window removes the changes.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!