How to draw an image over another image?

30,050

Solution 1

If this is Swing, then draw the background image in a BufferedImage. Display this BufferedImage in a JComponent's (such as a JPanel's) paintComponent method using Graphic's drawImage(...) method, and then draw the changing images over this in the same paintComponent method. Don't forget to call the super.paintComponent(...) method first though.

Please note that this question has been asked quite a bit here and elsewhere, and as you would expect, there are lots of examples of this sort of thing that you can find here with a bit of searching.

Edit
You ask:

Thanks, this is how I draw the firt image (road)

Again, you would create a BufferedImage for this, likely by using ImageIO.read(...). Then you'd draw this in your JPanel's paintComponent(Graphics g) method override using g.drawImage(...).

For example...

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.*;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class IntersectionImagePanel extends JPanel {
   private static final String INTERSECTION_LINK = "http://www.weinerlawoffice.com/" +
        "accident-diagram.jpg";
   private BufferedImage intersectionImage;

   public IntersectionImagePanel() {
      URL imageUrl;
      try {
         imageUrl = new URL(INTERSECTION_LINK);
         intersectionImage = ImageIO.read(imageUrl );
      } catch (MalformedURLException e) {
         e.printStackTrace();
         System.exit(-1);
      } catch (IOException e) {
         e.printStackTrace();
         System.exit(-1);
      }
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      if (intersectionImage != null) {
         g.drawImage(intersectionImage, 0, 0, this);
      }
   }

   @Override
   public Dimension getPreferredSize() {
      if (intersectionImage != null) {
         int width = intersectionImage.getWidth();
         int height = intersectionImage.getHeight();
         return new Dimension(width , height );
      }
      return super.getPreferredSize();
   }

   private static void createAndShowGui() {
      IntersectionImagePanel mainPanel = new IntersectionImagePanel();

      JFrame frame = new JFrame("IntersectionImage");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

Solution 2

Another approach that does not require extending components.

enter image description here

import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import java.util.Random;
import java.net.URL;
import javax.imageio.ImageIO;

public class ImageOnImage {

    ImageOnImage(final BufferedImage bg, BufferedImage fg) {
        final BufferedImage scaled = new BufferedImage(
            fg.getWidth()/2,fg.getHeight()/2,BufferedImage.TYPE_INT_RGB);
        Graphics g = scaled.getGraphics();
        g.drawImage(fg,0,0,scaled.getWidth(),scaled.getHeight(),null);
        g.dispose();

        final int xMax = bg.getWidth()-scaled.getWidth();
        final int yMax = bg.getHeight()-scaled.getHeight();

        final JLabel label = new JLabel(new ImageIcon(bg));

        ActionListener listener = new ActionListener() {

            Random random = new Random();

            public void actionPerformed(ActionEvent ae) {
                Graphics g = bg.getGraphics();
                int x = random.nextInt(xMax);
                int y = random.nextInt(yMax);

                g.drawImage( scaled, x, y, null );
                g.dispose();

                label.repaint();
            }
        };

        Timer timer = new Timer(1200, listener);
        timer.start();

        JOptionPane.showMessageDialog(null, label);
    }

    public static void main(String[] args) throws Exception {
        URL url1 = new URL("http://i.stack.imgur.com/lxthA.jpg");
        final BufferedImage image1 = ImageIO.read(url1);

        URL url2 = new URL("http://i.stack.imgur.com/OVOg3.jpg");
        final BufferedImage image2 = ImageIO.read(url2);

        //Create the frame on the event dispatching thread
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                new ImageOnImage(image2, image1);
            }
        });
    }
}
Share:
30,050
DZkid
Author by

DZkid

Updated on July 25, 2022

Comments

  • DZkid
    DZkid almost 2 years

    I have a Java project that's about traffic network simulation in a random city, I've managed to figure out a way to implement this project, so I divided each intersection into a section which is basically an extended JPanel class (named Carrefour)...everything works well until I got stuck with how to draw vehicles and make them pass through roads.

    So my problem is how to draw an image (vehicle image) over an another image (road)?

  • RafiAlhamd
    RafiAlhamd over 3 years
    This simply helped me, without the complexity of extending any component.
  • samuel zaffran
    samuel zaffran over 3 years
    Thx ! Great Solution !! Should be accepted answer !