Rotate 90 degree to right image in java

24,951

Solution 1

As discussed here, you can use AffineTransformOp to rotate an image by Math.PI / 2; this is equivalent to rotating the image clockwise 90°, as shown here. See also Handling 90-Degree Rotations.

Solution 2

We should definitely use Graphics2D if we want to have decent performance (~10x faster comparing to copying pixels directly):

public static BufferedImage rotateClockwise90(BufferedImage src) {
    int width = src.getWidth();
    int height = src.getHeight();

    BufferedImage dest = new BufferedImage(height, width, src.getType());

    Graphics2D graphics2D = dest.createGraphics();
    graphics2D.translate((height - width) / 2, (height - width) / 2);
    graphics2D.rotate(Math.PI / 2, height / 2, width / 2);
    graphics2D.drawRenderedImage(src, null);

    return dest;
}

Solution 3

Here is the code I used to rotate a BufferedImage clockwise 90 degrees. Since rotating by 90 degrees is a special case, I didn't think a solution that was generic for any angle would have optimal performance. Likewise for solutions that perform some sort of interpolation (bilinear, bicubic, etc.) I used BufferedImage.getRaster() to access the raw bytes in order to improve performance, but depending on the structure/layout of the image, this is not likely to work in all cases. YMMV.

public static BufferedImage rotateClockwise90(BufferedImage src) {

    int srcWidth = src.getWidth();
    int srcHeight = src.getHeight();
    boolean hasAlphaChannel = src.getAlphaRaster() != null;
    int pixelLength = hasAlphaChannel ? 4 : 3;
    byte[] srcPixels = ((DataBufferByte)src.getRaster().getDataBuffer()).getData();

    // Create the destination buffered image
    BufferedImage dest = new BufferedImage(srcHeight, srcWidth, src.getType());
    byte[] destPixels = ((DataBufferByte)dest.getRaster().getDataBuffer()).getData();
    int destWidth = dest.getWidth();

    int srcPos = 0; // We can just increment this since the data pack order matches our loop traversal: left to right, top to bottom. (Just like reading a book.)   
    for(int srcY = 0; srcY < srcHeight; srcY++) {
        for(int srcX = 0; srcX < srcWidth; srcX++) {

            int destX = ((srcHeight - 1) - srcY);
            int destY = srcX;

            int destPos = (((destY * destWidth) + destX) * pixelLength);

            if(hasAlphaChannel) {
                destPixels[destPos++] = srcPixels[srcPos++];    // alpha
            }
            destPixels[destPos++] = srcPixels[srcPos++];        // blue
            destPixels[destPos++] = srcPixels[srcPos++];        // green
            destPixels[destPos++] = srcPixels[srcPos++];        // red
        }
    }

    return dest;
}

Solution 4

A simplified version of Ken's answer:

public static BufferedImage rotateClockwise90(BufferedImage src) {
    int w = src.getWidth();
    int h = src.getHeight();
    BufferedImage dest = new BufferedImage(h, w, src.getType());
    for (int y = 0; y < h; y++) 
        for (int x = 0; x < w; x++) 
            dest.setRGB(y, w - x - 1, src.getRGB(x, y));
    return dest;
}

Solution 5

Rotate image to 90, 180 or 270 degree angle

public static BufferedImage rotateImage(BufferedImage src, int rotationAngle) {
    double theta = (Math.PI * 2) / 360 * rotationAngle;
    int width = src.getWidth();
    int height = src.getHeight();
    BufferedImage dest;
    if (rotationAngle == 90 || rotationAngle == 270) {
        dest = new BufferedImage(src.getHeight(), src.getWidth(), src.getType());
    } else {
        dest = new BufferedImage(src.getWidth(), src.getHeight(), src.getType());
    }

    Graphics2D graphics2D = dest.createGraphics();

    if (rotationAngle == 90) {
        graphics2D.translate((height - width) / 2, (height - width) / 2);
        graphics2D.rotate(theta, height / 2, width / 2);
    } else if (rotationAngle == 270) {
        graphics2D.translate((width - height) / 2, (width - height) / 2);
        graphics2D.rotate(theta, height / 2, width / 2);
    } else {
        graphics2D.translate(0, 0);
        graphics2D.rotate(theta, width / 2, height / 2);
    }
    graphics2D.drawRenderedImage(src, null);
    return dest;
}
Share:
24,951
Ertuğrul Çetin
Author by

Ertuğrul Çetin

Clojure Developer day by day LISP lover...Dreamer &amp; Maker

Updated on July 23, 2022

Comments

  • Ertuğrul Çetin
    Ertuğrul Çetin almost 2 years

    I can not rotate image 90 degree to right . I need to be able to rotate images individually in java. The only thing. Unfortunately, I need to draw the image at a specific point, and there is no method with an argument that 1.rotates the image separately and 2. allows me to set the x and y. any help is appreciated

    public class Tumbler extends GraphicsProgram{
    
    public void run() {
        setSize(1000,1000);
        GImage original = new GImage("sunset.jpg");
        add(original, 10, 10);
        int[][] pixels = original.getPixelArray();
        int height = pixels.length;
        int width = pixels[0].length;
    
        // Your code starts here
        int newheight = width;
        int newwidth = height;
        int[][] newpixels = new int[newheight][newwidth];
    
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {               
                newpixels[j][height-1-i] = pixels[i][j];            
            }
        }
    
    
        GImage image = new GImage(newpixels);
        add(image, width+20, 10);
    
        // Your code ends here
        }