在 Java Swing 上旋转 JLabel 或 ImageIcon
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4287499/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rotate JLabel or ImageIcon on Java Swing
提问by dgnin
first of all, this is the first week that I use swing, then sorry if my question is too obvious. Also, I need solutions that use the standard java libraries, since this is for homework and I'm not allowed to use strange libraries.
首先,这是我使用 Swing 的第一周,如果我的问题太明显,请见谅。另外,我需要使用标准 java 库的解决方案,因为这是用于家庭作业,我不允许使用奇怪的库。
I'm using JLabel with ImageIcon to show images on a JFrame. Now I want to rotate the image on screen to arbitrary angles. I found something about Graphics2D but i don't find the way to do that.
我使用 JLabel 和 ImageIcon 在 JFrame 上显示图像。现在我想将屏幕上的图像旋转到任意角度。我发现了一些关于 Graphics2D 的东西,但我没有找到这样做的方法。
Since solutions that I found doesn't work or I don't understand them, I'm interested in any solution to rotate the ImageIcon or the JLabel. Since I'm positioning the image doing setBounds on the JLabel, rotate the JLabel will be a better solution I think (this way I'm not forced to save the ImageIcon object too).
由于我发现的解决方案不起作用或我不理解它们,因此我对旋转 ImageIcon 或 JLabel 的任何解决方案感兴趣。由于我将图像定位在 JLabel 上执行 setBounds,因此我认为旋转 JLabel 将是一个更好的解决方案(这样我也不会被迫保存 ImageIcon 对象)。
Thank you for your attention and sorry for my bad English.
感谢您的关注,并为我的英语不好而感到抱歉。
Edit... To show the image in screen I do the next:
编辑...要在屏幕中显示图像,我执行以下操作:
JFrame frame = new JFrame("Something");
frame.setLayout(new FlowLayout()); //for example
JPanel panel = new JPanel();
panel.setLayout(null);
ImageIcon playerSprite = new ImageIcon("rute/to/file.png");
JLabel player = new JLabel(playerSprite);
panel.add(player);
player.setBounds(10,10,36,52); //for example
frame.getContentPane().add(panel);
frame.setVisible(true);
Resuming, how can I rotate this IconImage or the JLabel. I can use other method to show the image if you think that is better. If the solution is use Graphics2D, like I see, I will appreciate a solution to arrive to an object of this class an later return the rotated image to an ImageIcon, because when I try this...
继续,我如何旋转这个 IconImage 或 JLabel。如果您认为更好,我可以使用其他方法来显示图像。如果解决方案是使用 Graphics2D,就像我看到的那样,我会很欣赏一个解决方案来到达这个类的对象,然后将旋转后的图像返回到 ImageIcon,因为当我尝试这个时......
ImageIcon imagePlayer = new ImageIcon("img/stand.png");
Image image = imagePlayer.getImage();
Graphics2D g = (Graphics2D)image.getGraphics();
At execution time, the answer is this...
在执行时,答案是这样的......
Exception in thread "main" java.lang.UnsupportedOperationException: getGraphics() not valid for images created with createImage(producer)
2th edition... Now I'm working with this code. The image rotates but the old unrotated image still remains on screen under the new one. Put a png image called stand.png on the same directory and you will see it.
第 2 版...现在我正在使用此代码。图像旋转但未旋转的旧图像仍保留在新图像下方的屏幕上。将一个名为 stand.png 的 png 图像放在同一目录中,您将看到它。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.lang.Math;
public class Test {
public static void main(String args[]) throws Exception {
try {
JFrame frame = new JFrame("Rotation Test");
frame.setBounds(10,10,1008,756);
BufferedImage bi = ImageIO.read(new File("stand.png"));
Graphics2D g = (Graphics2D)bi.getGraphics();
g.rotate(Math.toRadians(45),26,26);
g.drawImage(bi, 0, 0, null);
JLabel player = new JLabel(new ImageIcon(bi));
frame.getContentPane().add(player);
player.setBounds(0,0,100,100);
frame.setVisible(true);
} catch (IOException ex) {
System.out.println("Exception");
}
}
}
采纳答案by trashgod
Instead of rotating the component itself, consider rotating the contentof a component. This exampledraws a rotated image in a JPanel
.
与其旋转组件本身,不如考虑旋转组件的内容。本示例在JPanel
.
Addendum: In the exampleRotatableImage.getImage()
creates a BufferedImage
directly in memory, but you can use ImageIO.read()
to obtain an image from elsewhere. BufferedImage#createGraphics()
is supported if you want to modify the image, but you probably just want to draw the unmodified image in a rotated graphics context as part of paintComponent()
.
附录:在示例中直接在内存中RotatableImage.getImage()
创建了一个BufferedImage
,但您可以使用ImageIO.read()
从其他地方获取图像。BufferedImage#createGraphics()
如果您想修改图像,则支持,但您可能只想在旋转的图形上下文中绘制未修改的图像作为paintComponent()
.
Addendum: You're painting over the image with a rotated copy; instead, draw the image into a rotated graphics context:
附录:您正在使用旋转副本在图像上绘画;相反,将图像绘制到旋转的图形上下文中:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
public static void main(String args[]) throws Exception {
JFrame frame = new JFrame("Rotation Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final BufferedImage bi = ImageIO.read(new File("img/stand.jpg"));
frame.add(new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(bi.getWidth(), bi.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.rotate(Math.PI / 4, bi.getWidth() / 2, bi.getHeight() / 2);
g2.drawImage(bi, 0, 0, null);
}
});
frame.pack();
frame.setVisible(true);
}
}
回答by camickr
Since solutions that I found doesn't work or I don't understand them
由于我找到的解决方案不起作用或我不理解它们
Well, if you don't understand them, then you should post your SSCCE (http://sscce.org) demonstrating your test code. Then maybe someone will be able to explain how the code work.
好吧,如果您不理解它们,那么您应该发布您的 SSCCE (http://sscce.org) 来演示您的测试代码。然后也许有人将能够解释代码的工作原理。
I doubt you would be able to understand any new code we might post since the concepts of rotation an image or an Icon are all the same.
我怀疑您是否能够理解我们可能发布的任何新代码,因为旋转图像或图标的概念都是相同的。
Since I'm positioning the image doing setBounds on the JLabel
由于我将图像定位在 JLabel 上执行 setBounds
Why are you using setBounds(). You should use a layout manager so you don't have to worry about this.
为什么要使用 setBounds()。您应该使用布局管理器,这样您就不必担心这一点。
Edit:
编辑:
Maybe you can use a Rotated Icon.
也许您可以使用Rotated Icon。