Game Development Community

Image rotation in Java

by Steve Fletcher · in Technical Issues · 04/19/2004 (6:21 pm) · 3 replies

I've been having some problems doing image manipulation with Java (Sun's version of Java). For example, I've been having a hard time rotating images 90 degrees. My image-rotating code follows. The top function is the function called to rotate an image - it calls the bottom 2 functions. If I rotate an image it works, but if I rotate image A into image B and then rotate image B into image C, image C is just a white square. Does anyone know what's going on? The images all have width == height.

If someone knows some alternate way to rotate images (within the code, not just having extra image files to load), I would like to hear about it. I suspect that this isn't the way it's supposed to be done.

/**	rotates an image 90 degrees
   @param image - the image to rotate
	INVARIANT: image must be fully loaded
	@return the rotated image*/
public Image rotateImage90Degrees(Image image) {
	int width = image.getWidth(mainFrame),
		height = image.getHeight(mainFrame);

	return rotateImage90Degrees(getPixels(image, width, height), width, height);
} //end rotateImage90Degrees

public int[] getPixels(Image image, int width, int height) {
	int[] aPixel = new int[width * height];
	PixelGrabber pixelGrabber = new PixelGrabber(image, 0, 0, width, height, aPixel,
				0, width);
	try {
		pixelGrabber.grabPixels();
	} catch(InterruptedException e) {
		GameEngine.error("Interrupted waiting for aPixel in " +
			"GameEngine.getPixels.  " + e.getMessage());
	}

	return aPixel;
} //end getPixels

/**	rotates an image 90 degrees
	@param image - the image to rotate
	INVARIANT: image must be fully loaded
	@return the rotated image*/
public Image rotateImage90Degrees(int[] aPixel, int width, int height) {
try {
	Image rotatedImage = mainFrame.createImage(width, height);
	Graphics g = rotatedImage.getGraphics();
	for(int j = 0; j < height; j++) {
		int x = height - j - 1;
		for(int i = 0; i < width; i++) {
			g.setColor(new Color(aPixel[j * width + i]));
			g.drawLine(x, i, x, i);
		}
	}

	g.dispose();

	//handle transparency
	Image finalImage = toolkit.createImage(new FilteredImageSource(rotatedImage.getSource(),
							   new TransparencyFilter()));
	tracker.addImage(finalImage, 6);
	return finalImage;
} catch(Exception e) {
	GameEngine.error("Error in GameEngine.rotateImage90Degrees.  " + e.getMessage());
}
	//should never get here
	return null;
} //end rotateImage90Degrees

#1
04/20/2004 (8:55 am)
That is really hard to read, and since it doesn't work, I will post something that should point you in the right direction.

Affine Transform is one way to do it! You rotate the entire coordinate system.

Here is an example I found it may or may not work.

import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.io.*;
import java.net.*;
import javax.imageio.*;
import javax.swing.*;

public class RotateImage {
    public static void main(String[] args) throws IOException {
        URL url = new URL("http://today.java.net/jag/bio/JagHeadshot-small.jpg");
        BufferedImage original = ImageIO.read(url);
        GraphicsConfiguration gc = getDefaultConfiguration();
        BufferedImage rotated1 = tilt(original, -Math.PI/2, gc);
        BufferedImage rotated2 = tilt(original, +Math.PI/2, gc);
        BufferedImage rotated3 = tilt(original, Math.PI, gc);
        display(original, rotated1, rotated2, rotated3);
    }

    public static BufferedImage tilt(BufferedImage image, double angle, GraphicsConfiguration gc) {
        double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle));
        int w = image.getWidth(), h = image.getHeight();
        int neww = (int)Math.floor(w*cos+h*sin), newh = (int)Math.floor(h*cos+w*sin);
        int transparency = image.getColorModel().getTransparency();
        BufferedImage result = gc.createCompatibleImage(neww, newh, transparency);
        Graphics2D g = result.createGraphics();
        g.translate((neww-w)/2, (newh-h)/2);
        g.rotate(angle, w/2, h/2);
        g.drawRenderedImage(image, null);
        return result;
    }

    public static GraphicsConfiguration getDefaultConfiguration() {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();
        return gd.getDefaultConfiguration();
    }

    public static void display(BufferedImage im1, BufferedImage im2, BufferedImage im3, BufferedImage im4) {
        JPanel cp = new JPanel(new GridLayout(2,2));
        addImage(cp, im1, "original");
        addImage(cp, im2, "rotate -PI/2");
        addImage(cp, im3, "rotate +PI/2");
        addImage(cp, im4, "rotate PI");

        JFrame f = new JFrame("RotateImage");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setContentPane(cp);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    static void addImage(Container cp, BufferedImage im, String title) {
        JLabel lbl = new JLabel(new ImageIcon(im));
        lbl.setBorder(BorderFactory.createTitledBorder(title));
        cp.add(lbl);
    }
}
#2
04/20/2004 (6:04 pm)
Thanks. I'll check out the code tomorrow morning. I imagine that it will probably work.
#3
04/28/2014 (12:55 am)
her is some sample codes on image rotation for you to test.
hope it works for you.
private void button1_Click(object sender, EventArgs e)
{
string fileName = "c:/Sample.png";

REImage reImage = REFile.OpenImageFile(fileName);

ImageProcessing.ApplyRotate(reImage, 60);

REFile.SaveImageFile(reImage, "c:/reimage.png", new PNGEncoder());
}