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