Come utilizzare AffineTransform.quadrantRotate per ruotare una bitmap?

Voglio ruotare una bitmap sul suo punto centrale e quindi disegnarla in un contesto grafico più ampio .

La bitmap è 40x40 pixels . Il contesto grafico è di 500x500 pixels . Questo è quello che sto facendo:

 BufferedImage bi = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB); Graphics2D g = bi.createGraphics(); AffineTransform at = new AffineTransform(); at.quadrantRotate(1, -20, -20); // rotate 90 degrees around center point. at.translate(100, 40); // I want to put its top-left corner at 100,40. g.drawImage(smallerBitmap, at, null); ... 

Probabilmente sto usando quadrantRotate() modo errato – se rimuovo quella linea, la mia immagine viene disegnata correttamente almeno alla posizione 100,40 .

Che cosa sto facendo di sbagliato?

Grazie

L’ordine della tua trasformazione è importante. Fondamentalmente il tuo codice di esempio sta dicendo “ruotare l’immagine di 90 gradi e poi tradurla …”

Quindi, usando il tuo codice (ruota, poi traduci) produce …

Cattivo rotazione

Commuta l’ordine (tradurre quindi ruotare)

Buona rotazione

 import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public class TestRotation100 { public static void main(String[] args) { new TestRotation100(); } public TestRotation100() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } final TestPane testPane = new TestPane(); final JSlider slider = new JSlider(0, 3); slider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { testPane.setQuad(slider.getValue()); } }); slider.setValue(0); JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(testPane); frame.add(slider, BorderLayout.SOUTH); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private BufferedImage img; private int quad = 0; public TestPane() { try { img = ImageIO.read(new File("/Users/swhitehead/Dropbox/MegaTokyo/Rampage_Small.png")); } catch (IOException ex) { ex.printStackTrace(); } } public void setQuad(int quad) { this.quad = quad; repaint(); } @Override public Dimension getPreferredSize() { return new Dimension(400, 400); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); AffineTransform at = new AffineTransform(); at.translate(100, 40); at.quadrantRotate(quad, img.getWidth() / 2, img.getHeight() / 2); g2d.drawImage(img, at, this); g2d.dispose(); } } }