问题
I'm creating a domino game in java. I have the following code that loads, resizes and then display the domino image on the screen:
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);
What I want to do is rotate the image either 90 or -90 degrees. I've searched the internet but the examples I've found seems very complicated.
Any idea how I can rotate my image?
Btw, if you think that this is not the correct way to display dominoes in a domino game then please let me know. I'me a java newbie.
回答1:
Rotating an image is non-trival, even just 90 degrees requires a certain amount of work.
So, based on pretty much every other question about rotating images, I'd start with something like...
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;
}
While you're only rotate 90 degrees, this takes care of calculating the required size the new image needs in order to be able to paint the rotated image, at any angle.
It then simply makes use of AffineTransform to manipulate the origin point from which painting occurs - get use to this, you will do it a lot.
Then, I load the images, rotate them and display them...
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();
}
I prefer to use ImageIO to load images, because it throws an IOException
when something goes wrong, rather then failing silently like ImageIcon
.
You should also be embedding your resources within your application's context, this makes it easier to load them at runtime. Depending on IDE and how your project is set up, how you do this will change, but in "most" cases, you should be able to add the resource directly to your source directory (preferably in sub directory) and the IDE will make it available for you and package it when you export the project
回答2:
Solution from: 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);
来源:https://stackoverflow.com/questions/50883802/how-to-rotate-an-imageicon-in-java