Java 在另一个图像上旋转图像

Java 在另一个图像上旋转图像,java,image,swing,rotation,image-rotation,Java,Image,Swing,Rotation,Image Rotation,我有一种方法,当用户输入旋转图像的度数时,我希望旋转图像。这个方法可以做到这一点,但问题是它正在旋转图像,以便新图像位于旧图像之上,而我不希望它这样做;我只想要新形象本身。RotateTest只是类的缩写形式,包含ButtonListener类中需要的所有与旋转图像相关的方法 public class RotateTest { public Rotate() { try { String path = "default.jpg";

我有一种方法,当用户输入旋转图像的度数时,我希望旋转图像。这个方法可以做到这一点,但问题是它正在旋转图像,以便新图像位于旧图像之上,而我不希望它这样做;我只想要新形象本身。RotateTest只是类的缩写形式,包含ButtonListener类中需要的所有与旋转图像相关的方法

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());
        }
}

谢谢

您的代码对我来说似乎是正确的,我看不出明显的错误。尽管如此,以下功能仍适用于我的旋转图像,因此它也应该是您的解决方案:

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;
}
辅助函数:

/**
 * 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;
    }
}
将JLabels图标顺时针旋转90度的示例用法:

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)));

非常感谢。我不需要使用JLabel,因为我使用的是paint,但很高兴看到它是如何完成的,以供将来参考。我有没有办法设置一个锚点,使图像围绕中心旋转?现在,如果我先旋转90度,然后再旋转45度,然后按下复位按钮(actionPerformed方法中的else语句),左上角将移动到图像的中间,而不是左上角。有办法解决这个问题吗?谢谢为了提供重置功能,我只需将原始图片保存在一个额外的变量中,并在按下重置按钮时将其设置回原始图片。如果您不想提供撤销功能,只需记录执行的操作,并在撤销时将其反转,如:旋转20;轮换-10次;[撤消]->旋转-1*-10;[撤消]旋转-1*20等。
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)));