Rotate BufferedImage in Java

Simple method that correctly rotates a BufferedImage.

The code you find on the web usually has lots of bugs:

  • Does not create image of correct size.
  • Does not use correct offset.
  • Unnecessarily rotates by .
  • Does not work for negative angles (e.g. -90°).
  • Does not consider BufferedImage.TYPE_CUSTOM.
  • Does not dispose Graphics2D.

Or it just doesn’t work. Mine is tested and works fine. Some are overly complicated using AffineTransform. That works, but is not necessary. Then there are methods that allow to rotate at any angle, while mine only works for multiples of 90°. It also automatically returns the original image if rotation is a multiple of 360° (including 0°).

Obviously, you should use an Enum for the angle, so that it is clear what angles are actually supported but I tried to keep it simple. This also has the advantage that you can use -90 instead of 270. Feel free to change the code when you use it.

The Code:
package ch.claude_martin.foo;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class SomeClass {
	public static void main(String[] args) throws IOException {
		var input = "C:/picture.jpg";
		var output = "C:/rotated_picture.jpg";
		var img = ImageIO.read(new File(input));
		var rotated = rotateBufferedImage(img, -90);
		ImageIO.write(rotated, "jpg", new File(output));
	}

	/**
	 * Rotates an image. Note that an angle of -90 is equal to 270.
	 * 
	 * @param img   The image to be rotated
	 * @param angle The angle in degrees (must be a multiple of 90°).
	 * @return The rotated image, or the original image, if the effective angle is
	 *         0°.
	 */
	public static BufferedImage rotateBufferedImage(BufferedImage img, int angle) {
		if (angle < 0) {
			angle = 360 + (angle % 360);
		}
		if ((angle %= 360) == 0) {
			return img;
		}
		final boolean r180 = angle == 180;
		if (angle != 90 && !r180 && angle != 270)
			throw new IllegalArgumentException("Invalid angle.");
		final int w = r180 ? img.getWidth() : img.getHeight();
		final int h = r180 ? img.getHeight() : img.getWidth();
		final int type = img.getType() == BufferedImage.TYPE_CUSTOM ? BufferedImage.TYPE_INT_ARGB : img.getType();
		final BufferedImage rotated = new BufferedImage(w, h, type);
		final Graphics2D graphic = rotated.createGraphics();
		graphic.rotate(Math.toRadians(angle), w / 2d, h / 2d);
		final int offset = r180 ? 0 : (w - h) / 2;
		graphic.drawImage(img, null, offset, -offset);
		graphic.dispose();
		return rotated;
	}

}
Code on Pastebin:

https://pastebin.com/SnKS7kip

Leave a Reply

Your email address will not be published.