Java code to easily rotate a buffered image.
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
0°
. - 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;
}
}