How to draw on top of an image in Java?

自闭症网瘾萝莉.ら 提交于 2019-12-02 18:06:19

问题


I used JFrame to import and display an image, and used mousemotionlistener to detect the mouse clicks, and I want to be able to draw on top of the image. I want to be able to, if the user makes a click, make that pixel a certain color while preserving the rest of the image, however, I couldn't find out how to use Graphics to do so without deleting the rest of the image or opening a new window.

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

回答1:


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




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/43081526/how-to-draw-on-top-of-an-image-in-java

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