Drehen Sie BufferedImage innerhalb von JPanel

Ich versuche, ein JLabel zu drehen und es in einem JLabel (das in einem JPanel ) JPanel . Das aktuelle Ergebnis erzeugt ein weißes Quadrat, das um 10 Grad gegen einen schwarzen Hintergrund gedreht ist, aber das Bild ist nicht innerhalb des Quadrats vorhanden. Ich weiß, dass myPicture nicht leer ist, da myPicture selbst im JPanel korrekt JPanel wenn es nicht gedreht wird.

Hier ist der Code:

 int w = myPicture.getWidth(); int h = myPicture.getHeight(); BufferedImage newImage = new BufferedImage(w, h, myPicture.getType()); Graphics2D graphic = newImage.createGraphics(); graphic.rotate(Math.toRadians(10), w/2, h/2); graphic.drawImage(myPicture, null, 0, 0); picLabel.setIcon(new ImageIcon(newImage)); 

   

Es gibt nicht viel zu tun, aber zwei Dinge kommen mir in den Sinn. Es ist möglich, dass das Bild nicht an der richtigen Position gerendert wird, nachdem es gedreht wurde, und zwei, Sie entledigen sich des Grafikkontexts nicht, wenn Sie damit fertig sind (nicht dass ich glaube, dass es einen Effekt haben sollte, aber Sie niemals kennt).

Dies ist ein einfaches Beispiel, das das Ergebnis über paintComponent , aber das Konzept ist das gleiche.

Es verwendet eine AffineTransformation , um das Bild zu drehen.

Bildbeschreibung hier eingeben

 import java.awt.BorderLayout; import java.awt.Color; 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 java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.UIManager; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public class TestRotateImage { public static void main(String[] args) { new TestRotateImage(); } public TestRotateImage() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception ex) { } JFrame frame = new JFrame("Test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private JSlider slider; private BufferedImage image; public TestPane() { setLayout(new BorderLayout()); try { image = ImageIO.read(new File("/path/to/your/image")); } catch (IOException ex) { ex.printStackTrace(); } slider = new JSlider(); slider.setMinimum(0); slider.setMaximum(360); slider.setMinorTickSpacing(5); slider.setMajorTickSpacing(10); slider.setValue(0); add(slider, BorderLayout.SOUTH); slider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { repaint(); } }); } @Override public Dimension getPreferredSize() { return image == null ? new Dimension(200, 200) : new Dimension(image.getWidth(), image.getHeight()); } public double getAngle() { return Math.toRadians(slider.getValue()); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); g2d.setColor(Color.RED); g2d.drawLine(getWidth() / 2, 0, getWidth() / 2, getHeight()); g2d.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2); g2d.setColor(Color.BLACK); int x = (getWidth() - image.getWidth()) / 2; int y = (getHeight() - image.getHeight()) / 2; AffineTransform at = new AffineTransform(); at.setToRotation(getAngle(), x + (image.getWidth() / 2), y + (image.getHeight() / 2)); at.translate(x, y); g2d.setTransform(at); g2d.drawImage(image, 0, 0, this); g2d.dispose(); } } } 

Aktualisieren Sie mit einem JLabel

Bildbeschreibung hier eingeben

 import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; 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.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.UIManager; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public class TestRotateImage { public static void main(String[] args) { new TestRotateImage(); } public TestRotateImage() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception ex) { } JFrame frame = new JFrame("Test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private JSlider slider; private BufferedImage image; private JLabel label; public TestPane() { setLayout(new BorderLayout()); label = new JLabel(); label.setHorizontalAlignment(JLabel.CENTER); label.setVerticalAlignment(JLabel.CENTER); try { image = ImageIO.read(new File("/path/to/your/image")); label.setIcon(new ImageIcon(image)); } catch (IOException ex) { ex.printStackTrace(); } add(label); slider = new JSlider(); slider.setMinimum(0); slider.setMaximum(360); slider.setMinorTickSpacing(5); slider.setMajorTickSpacing(10); slider.setValue(0); add(slider, BorderLayout.SOUTH); slider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { double radians = Math.toRadians(slider.getValue()); 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); BufferedImage rotate = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = rotate.createGraphics(); int x = (newWidth - image.getWidth()) / 2; int y = (newHeight - image.getHeight()) / 2; AffineTransform at = new AffineTransform(); at.setToRotation(getAngle(), x + (image.getWidth() / 2), y + (image.getHeight() / 2)); at.translate(x, y); g2d.setTransform(at); g2d.drawImage(image, 0, 0, TestPane.this); g2d.dispose(); label.setIcon(new ImageIcon(rotate)); } }); } @Override public Dimension getPreferredSize() { return image == null ? new Dimension(200, 200) : new Dimension(image.getWidth(), image.getHeight()); } public double getAngle() { return Math.toRadians(slider.getValue()); } } } 

Ich habe mein eigenes Problem getriggers. Das Problem lag im Code:

 myPicture.getType() 

Da die Arten von Bildern, die Sie in das Programm einfügen können, sehr unterschiedlich sind, sind die Ergebnisse unvorhersehbar, wenn Sie mit dem Zeichnen in das neue BufferedImage beginnen. Ich habe das Problem getriggers, indem ich den Typ explizit gesetzt habe, was in meinem Fall erforderlich war

 BufferedImage.TYPE_INT_ARGB 

so die vollständige Aussage gelesen:

 BufferedImage newImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);