简体   繁体   中英

Masking a BufferedImage

How would you overlay two BufferedImage objects on top of each other on specific parts?

Let's say you have two BufferedImage objects, and you have a list of Rectangle2D objects. You want to overwrite the first BufferedImage with the second BufferedImage at the rectangles. How would you do this?

You use TexturePaint and draw a rectangle!

First you create a output image using BufferedImage result = new BufferedImage(<width>,<height>,<colorMode>) , then you create and get the Graphics2D object using Graphics2D g = result.createGraphics() .

Then you draw the full source image (Image1) onto the output image using g.drawImage(<sourceImage>, null, 0, 0) .

To overlay the BufferedImage we will use TexturePaint and the g.fill(rect) method; You want to loop through all of the rectangles using a for loop like this: for (Rectangle2D rect: rectangles) In the constructor for the TexturePaint you use the BufferedImage.getSubImage(int x, y, width, height) method to crop the image on the rectangle to get the part of the overlay (Image2) you want, then in the second part you use the Rectangle2D to fit the image to make sure that it doesn't stretch. After that you use g.fill(rect) to draw the (textured) rectangle onto the output image.

Finally you can do whatever you want with the output image. In the following example I exported it into a .png file using ImageIO .

Example:

Image1: https://i.stack.imgur.com/L0Z2k.jpg
Image2: https://i.stack.imgur.com/cmiAR.jpg
Output: https://i.stack.imgur.com/KgNM2.png

Code:

package test;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class ImageMasking {

    // Define rectangles
    public static Rectangle2D[] rectangles = new Rectangle[]{
            new Rectangle(0, 0, 350, 50),
            new Rectangle(0, 0, 50, 225),
            new Rectangle(0, 175, 350, 50)
    };

    public static void main(String[] args) throws IOException {
        // Load images
        BufferedImage image1 = ImageIO.read(new File("image1.jpg"));
        BufferedImage image2 = ImageIO.read(new File("image2.jpg"));

        // Create output file
        File out = new File("out.png");
        if (!out.exists()) {
            if (!out.createNewFile()) {
                throw new IOException("createNewFile() returned false");
            }
        }

        // Create output image
        BufferedImage result = new BufferedImage(image1.getWidth(), image1.getHeight(), 
            BufferedImage.TYPE_INT_RGB);
        Graphics2D g = result.createGraphics();

        // Draw image1 onto the result
        g.drawImage(image1, null, 0, 0);

        // Masking
        for (Rectangle2D rect : rectangles){
            // Extract x, y, width and height for easy access in the getSubImage method.
            int x = (int) rect.getX();
            int y = (int) rect.getY();
            int width = (int) rect.getWidth();
            int height = (int) rect.getHeight();
            
            // Setup and draw the rectangle
            TexturePaint paint = new TexturePaint(image2.getSubimage(x,y,width,height), rect);
            g.setPaint(paint);
            g.fill(rect);
        }

        // Export image
        ImageIO.write(result, "PNG", out);
    }
}

// Edits ToDo: Create an easy access method for this, but as I am on my phone right now I can't really code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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