user489041
user489041

Reputation: 28294

Rotate an image in java

I am looking to rotate an image. I have a JInternalFrame which contains a JLabel. The label contains the image. After the image has been rotated, I need to resize the internal frame. The code I have currently rotates the image, but there is black around the edges of the image and it is off centered. Any suggestions on how to fix this?

public void rotateIcon(int angle)
{
        int w = theLabel.getIcon().getIconWidth();
        int h = theLabel.getIcon().getIconHeight();
        int type = BufferedImage.TYPE_INT_RGB;  // other options, see api

        BufferedImage DaImage = new BufferedImage(h, w, type);
        Graphics2D g2 = DaImage.createGraphics();

        double x = (h - w)/2.0;
        double y = (w - h)/2.0;
        AffineTransform at = AffineTransform.getTranslateInstance(x, y);

        at.rotate(Math.toRadians(angle), w/2.0, h/2.0);
        g2.drawImage(new ImageIcon(getData()).getImage(), at, theLabel);
        g2.dispose();

        theLabel.setIcon(new ImageIcon(DaImage));
        this.setSize(DaImage.getWidth(),DaImage.getHeight()); //resize the frame
}

Upvotes: 9

Views: 38541

Answers (4)

user1050755
user1050755

Reputation: 11691

Based on a previous example, but actually working with recent JDKs and in headless mode:

public static BufferedImage rotate(BufferedImage image, double angle) {
    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);
    BufferedImage result = deepCopy(image, false);
    Graphics2D g = result.createGraphics();
    g.translate((neww - w) / 2, (newh - h) / 2);
    g.rotate(angle, w / 2, h / 2);
    g.drawRenderedImage(image, null);
    g.dispose();
    return result;
}

public static BufferedImage deepCopy(BufferedImage bi, boolean copyPixels) {
    ColorModel cm = bi.getColorModel();
    boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
    WritableRaster raster = bi.getRaster().createCompatibleWritableRaster();
    if (copyPixels) {
        bi.copyData(raster);
    }
    return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
}    

Upvotes: 1

Reverend Gonzo
Reverend Gonzo

Reputation: 40811

You need to be using trigonometry to determine the correct width/height, using transparency to prevent the black area, and I think the Transform is wrong, which is making it off center.

Try this:

public static BufferedImage rotate(BufferedImage image, double angle) {
    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);
    GraphicsConfiguration gc = getDefaultConfiguration();
    BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT);
    Graphics2D g = result.createGraphics();
    g.translate((neww - w) / 2, (newh - h) / 2);
    g.rotate(angle, w / 2, h / 2);
    g.drawRenderedImage(image, null);
    g.dispose();
    return result;
}

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

from http://flyingdogz.wordpress.com/2008/02/11/image-rotate-in-java-2-easier-to-use/

Upvotes: 19

bjoernz
bjoernz

Reputation: 3852

Does it help if you change:

BufferedImage DaImage = new BufferedImage(height, width, type);

to:

BufferedImage DaImage = new BufferedImage(**width, height**, type);?

Upvotes: 0

camickr
camickr

Reputation: 324118

You could try using a Rotated Icon.

Upvotes: 5

Related Questions