【问题标题】:How to rotate an imageIcon in Java如何在 Java 中旋转 imageIcon
【发布时间】:2018-11-25 18:49:58
【问题描述】:

我正在用 java 创建一个多米诺骨牌游戏。我有以下代码可以加载、调整大小然后在屏幕上显示多米诺骨牌图像:

ImageIcon imageIcon = new ImageIcon("images\\4-4.png");
Image image = imageIcon.getImage(); 
Image newimg = image.getScaledInstance(60, 120,  java.awt.Image.SCALE_SMOOTH);  
imageIcon = new ImageIcon(newimg);

JLabel img = new JLabel(imageIcon);
img.setBounds(100, 100, 60, 120);
getContentPane().add(img);

我想要做的是将图像旋转 90 度或 -90 度。我搜索了互联网,但我找到的示例似乎非常复杂。

知道如何旋转我的图像吗?

顺便说一句,如果您认为这不是在多米诺骨牌游戏中显示多米诺骨牌的正确方式,请告诉我。我是java新手。

【问题讨论】:

  • "..但是我发现的例子看起来很复杂。" 链接到你发现的三个最简单的例子。在我们确定您认为“复杂”的内容之前,任何人试图回答这个问题都是毫无意义的。
  • “如果您认为这不是在多米诺骨牌游戏中显示多米诺骨牌的正确方式,请告诉我” Unicode 字符集包括多米诺骨牌。如果不使用它们,我倾向于在它们进入应用程序之前缩放和旋转图块。
  • "我在网上搜索过,但我发现的例子似乎很复杂。" - 为什么你认为我们提供的任何解决方案都不会是"复杂的”?旋转图像(并放大图像以适应)将需要一些触发,这总是很复杂(对我来说)
  • I've searched the internet but the examples I've found seems very complicated. - 使用Rotated Icon 怎么样。它是一个可重用的类,您只需在一行代码中选择旋转角度。
  • 如果图像的数量在原点已知,为什么不要求资源中的所有旋转图像?旋转图像是一项繁重/漫长的)操作...

标签: java image swing java-2d affinetransform


【解决方案1】:

旋转图像并非易事,即使只是 90 度也需要一定的工作量。

所以,基于几乎所有其他关于旋转图像的问题,我会从类似...

public BufferedImage rotate(BufferedImage image, Double degrees) {
    // Calculate the new size of the image based on the angle of rotaion
    double radians = Math.toRadians(degrees);
    double sin = Math.abs(Math.sin(radians));
    double cos = Math.abs(Math.cos(radians));
    int newWidth = (int) Math.round(image.getWidth() * cos + image.getHeight() * sin);
    int newHeight = (int) Math.round(image.getWidth() * sin + image.getHeight() * cos);

    // Create a new image
    BufferedImage rotate = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2d = rotate.createGraphics();
    // Calculate the "anchor" point around which the image will be rotated
    int x = (newWidth - image.getWidth()) / 2;
    int y = (newHeight - image.getHeight()) / 2;
    // Transform the origin point around the anchor point
    AffineTransform at = new AffineTransform();
    at.setToRotation(radians, x + (image.getWidth() / 2), y + (image.getHeight() / 2));
    at.translate(x, y);
    g2d.setTransform(at);
    // Paint the originl image
    g2d.drawImage(image, 0, 0, null);
    g2d.dispose();
    return rotate;
}

虽然您只旋转 90 度,但它会计算新图像所需的大小,以便能够以任意角度绘制旋转后的图像。

然后它简单地使用AffineTransform 来操纵绘画发生的原点 - 习惯这个,你会做很多。

然后,我加载图像,旋转它们并显示它们......

try {
    BufferedImage original = ImageIO.read(getClass().getResource("domino.jpg"));
    BufferedImage rotated90 = rotate(original, 90.0d);
    BufferedImage rotatedMinus90 = rotate(original, -90.0d);

    JPanel panel = new JPanel();
    panel.add(new JLabel(new ImageIcon(original)));
    panel.add(new JLabel(new ImageIcon(rotated90)));
    panel.add(new JLabel(new ImageIcon(rotatedMinus90)));

    JOptionPane.showMessageDialog(null, panel, null, JOptionPane.PLAIN_MESSAGE, null);
} catch (IOException ex) {
    ex.printStackTrace();
}

我更喜欢使用ImageIO 来加载图像,因为它会在出现问题时抛出IOException,而不是像ImageIcon 那样默默地失败。

您还应该将资源嵌入到应用程序的上下文中,这样可以更轻松地在运行时加载它们。根据 IDE 和项目的设置方式,执行此操作的方式会有所不同,但在“大多数”情况下,您应该能够将资源直接添加到源目录(最好在子目录中)并且 IDE 会实现可供您使用并在您导出项目时打包它

【讨论】:

  • 谢谢。我更改了一些小细节,但您的解决方案有效!
  • AffineTransform 具有旋转方法,因此您不必摆弄三角法。 Java 有一个AffineTransformOp,因此您不必自己摆弄图像和图形,尽管有报告称您无法控制质量(使用Graphics2D,您可以自己控制所有质量参数)。
  • @MarkJeronimus 是的,我全部使用了 - 三角函数用于计算新图像的结果大小。当然,你可以在绘画过程中做这种事情,但是复合变换会变得混乱,此外,我读到的问题是如何获取现有图像并旋转它,创建一个新图像
  • @MarkJeronimus 所以,我在搞砸你的解决方案(因为找到更好的做某事的方法总是很好),我有一张600x315 的图像,我旋转了 90 度,其中,使用您的解决方案游戏时,结果为457x457 而不是315x600。如果我使用不同的旋转(比如 45 度),它仍然会返回不正确的结果并截断图像
【解决方案2】:

解决方案来自:http://www.java2s.com/Code/Java/Advanced-Graphics/RotatingaBufferedImage.htm

AffineTransform tx = new AffineTransform();
tx.rotate(0.5, bufferedImage.getWidth() / 2, bufferedImage.getHeight() / 2);

AffineTransformOp op = new AffineTransformOp(tx,
    AffineTransformOp.TYPE_BILINEAR);
bufferedImage = op.filter(bufferedImage, null);

【讨论】:

    猜你喜欢
    • 2022-11-20
    • 2012-12-17
    • 1970-01-01
    • 2017-03-25
    • 1970-01-01
    • 2012-11-04
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    相关资源
    最近更新 更多