Question

I have a method that I want to rotate an image when the user enters the number of degrees to rotate it. The method does that, but the thing is it's rotating the image so that the new image lays on top of the old one (which I don't want it to do; I just want the new image by itself). The RotateTest is just an abbreviated form of the class with all of the methods needed in the ButtonListener class that should be relevant to rotating the image.

public class RotateTest {
    public Rotate() {
        try {
            String path = "default.jpg";
            File imageFile = new File(path);
            imageURL = imageFile.toURI().toURL();
            image = ImageIO.read(imageURL);
            this.imageLabel = new JLabel(imageLabel);
        } catch (IOException e) { }
    }

    public void setAngle(double angle) {
        this.angle = angle;
    }

    public void setImage(BufferedImage img) {
        this.image = img;
    }

private class ButtonListener implements ActionListener {
    public void actionPerformed(ActionEvent event) {
        boolean doAgain = true;
        Artsy artsy = new Artsy();
    if(event.getSource() == rotate) {
            //need something for cancel!
            do {
                String angleString = JOptionPane.showInputDialog("Please enter your angle in degrees.");
                double angle = Double.parseDouble(angleString);
                if(angle < 0) {
                    angle = 360 + angle;
                }
                setAngle(getAngle() + angle);
                setImage(artsy.doRotate(image, angle));
                revalidate();
                repaint();
                System.out.println("The angle is " + getAngle());
            } while(JOptionPane.OK_OPTION == 1);
        }
        else {
            if(doAgain) {
                setImage(artsy.doRotate(image, 360 - getAngle()));
                doAgain = false;
                setAngle(0);
            }
            revalidate();
            repaint();
            System.out.println("The angle is " + getAngle());
        }
}

}

And this is the other class with the method that rotates the image:

public class Artsy {
    public BufferedImage doRotate(BufferedImage src, double angle) {    
        angle = Math.toRadians(angle);
        Graphics2D g = (Graphics2D) src.getGraphics();      
        int w = src.getWidth();
        int h = src.getHeight();
        AffineTransform trans = new AffineTransform();
        trans.rotate(angle, w / 2, h / 2);
        AffineTransformOp scaleOp = new AffineTransformOp(trans, AffineTransformOp.TYPE_BILINEAR);
        g.drawImage(scaleOp.filter(src, null), 0, 0, null);
        g.dispose();
        return src;
    }
}

Thank you!!

Was it helpful?

Solution

Your code seems correct to me, i can't see an obvious mistake. Nevertheless the following function is working for my to rotate images so it should also be a solution for you:

public static BufferedImage rotate(BufferedImage srcImage, double angle)
{
    double sin = Math.abs(Math.sin(Math.toRadians(angle))), cos = Math.abs(Math.cos(Math.toRadians(angle)));

    int originWidth = srcImage.getWidth(), originHeight = srcImage.getHeight();

    int newWidth = (int) Math.floor(originWidth * cos + originHeight * sin), newHeight = (int) Math.floor(originHeight * cos + originWidth * sin);

    BufferedImage newImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g = newImage.createGraphics();

    g.translate((newWidth - originWidth) / 2, (newHeight - originHeight) / 2);
    g.rotate(Math.toRadians(angle), originWidth / 2, originHeight / 2);
    g.drawImage(srcImage, 0, 0, null);
    g.dispose();

    return newImage;
}

A helper function:

/**
 * Converts an Icon to an Image
 */
public static Image iconToImage(Icon icon) {
    if (icon instanceof ImageIcon) {
        return ((ImageIcon) icon).getImage();
    }
    else {
        int w = icon.getIconWidth();
        int h = icon.getIconHeight();
        GraphicsEnvironment ge =
                GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();
        GraphicsConfiguration gc = gd.getDefaultConfiguration();
        BufferedImage image = gc.createCompatibleImage(w, h);
        Graphics2D g = image.createGraphics();
        icon.paintIcon(null, g, 0, 0);
        g.dispose();
        return image;
    }
}

Example usage to rotate the JLabels icon for 90 degrees clockwise:

BufferedImage buImg = new BufferedImage(imageLabel.getIcon().getIconWidth(), imageLabel.getIcon().getIconHeight(), BufferedImage.TYPE_INT_ARGB);
buImg.getGraphics().drawImage(iconToImage(imageLabel.getIcon()), 0, 0, null);
imageLabel.setIcon(new ImageIcon(rotate(buImg, 90)));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top