Search code examples
javaimagebitmapbufferedimageimage-resizing

Resize Java BufferedImage keeping aspect ratio and fill with background


I'm working with Java to store and modify .jpg images, (not Android or Swing). I want to transform an image with a new dimension keeping the aspect ratio and filling the background with white color if the new dimension is not proportional to the original image.

 BufferedImage image = /*Here i read from disk and load the image */;
 image = resizeImage(image,  newWidth, newHeight);
 ImageIO.write(image, extension, new File(filename + "_" + page + "." + extension));

The function I'm trying to implement is resizeImage: in the example resizes the image but it doesn't keep the aspect ratio.

  private static BufferedImage resizeImage(BufferedImage originalImage, int width, int height) {
        BufferedImage resizedImage = new BufferedImage(width, height, originalImage.getType());
        Graphics2D g = resizedImage.createGraphics();
        g.drawImage(originalImage, 0, 0, width, height, null);
        g.dispose();
        return resizedImage;
    }

I think a picture will be more illustrative of what I'm asking for: Function image behaviour

If the original image is 200x200 and is asked to resize to 400x300 the result should be a picture with white margin and the original picture resized inside. In this example should be 300x300.

The problem is not how to resize, it's how to fill the remaining image with white and the original resized image on the center of it.


Solution

  • This code worked for me:

    private static BufferedImage resizeImage(BufferedImage originalImage, int newWidth, int newHeight) {
        BufferedImage resizedImage = new BufferedImage(newWidth, newHeight, originalImage.getType());
        Graphics2D graphics = resizedImage.createGraphics();
        graphics.setColor(Color.WHITE);
        // fill the entire picture with white
        graphics.fillRect(0, 0, newWidth, newHeight);
        int maxWidth = 0;
        int maxHeight = 0;
        // go along the width and height in increments of 1 until one value is equal to the specified resize value
        while (maxWidth <= newWidth && maxHeight <= newHeight)
        {
            ++maxWidth;
            ++maxHeight;
        }
        // calculate the x value with which the original image is centred
        int centerX = (resizedImage.getWidth() - maxWidth) / 2;
        // calculate the y value with which the original image is centred
        int centerY = (resizedImage.getHeight() - maxHeight) / 2;
        // draw the original image
        graphics.drawImage(originalImage, centerX, centerY, maxWidth, maxHeight, null);
        graphics.dispose();
        return resizedImage;
    }
    

    Before: enter image description here

    After: enter image description here