The basic problem is, you're trying to rotate the entire Graphics
context around the centre point of the image, if it were been drawn from the top/left corner of the context (0x0), but the image is offset.
Because rotating images with virtual space is so much fun, I prefer to generate a new image rotated within its own context and then simply paint that. For example
If that seems like to much work, then you will need to first translate the Graphics
context in such away that the top/left corner is where the image is to be painted from, then you'll be able to rotate the image simple around it's centre/anchor point, for example:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
private BufferedImage img;
private double rotationByDegrees = 45.0;
public TestPane() throws IOException {
img = ImageIO.read(new File("/Users/shanewhitehead/Downloads/L05HK.png"));
}
@Override
public Dimension getPreferredSize() {
return img == null ? super.getPreferredSize() : new Dimension(img.getWidth(), img.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - img.getWidth()) / 2;
int y = (getHeight() - img.getHeight()) / 2;
g2d.translate(x, y);
g2d.rotate(Math.toRadians(rotationByDegrees), img.getWidth() / 2, img.getHeight() / 2);
g2d.drawImage(img, 0, 0, this);
g2d.dispose();
}
}
}
}
Note: You could also use a AffineTransform
, but I've just kept it simple