问题描述
我正在尝试在 java 中旋转缓冲图像.这是我正在使用的代码:
public static BufferedImage rotate(BufferedImage bimg, double angle) {int w = bimg.getWidth();int h = bimg.getHeight();Graphics2D 图形 = bimg.createGraphics();图形.旋转(Math.toRadians(角度),w/2,h/2);图形.drawImage(bimg, null, 0, 0);图形.dispose();返回 bimg;}
我查看了有关此主题的大量堆栈溢出问题和答案,但无法弄清楚为什么图像会像我尝试旋转它时那样被切碎.这是一个显示加载图像的示例:
还有这段代码……
package javaapplication1.pkg040;导入 java.awt.Color;导入 java.awt.Dimension;导入 java.awt.EventQueue;导入 java.awt.Graphics;导入 java.awt.Graphics2D;导入 java.awt.event.ActionEvent;导入 java.awt.event.ActionListener;导入 java.awt.geom.AffineTransform;导入 java.awt.image.BufferedImage;导入java.io.File;导入 java.io.IOException;导入 javax.imageio.ImageIO;导入 javax.swing.JFrame;导入 javax.swing.JPanel;导入 javax.swing.Timer;导入 javax.swing.UIManager;导入 javax.swing.UnsupportedLookAndFeelException;公共类测试{公共静态无效主要(字符串[]参数){新测试();}公共测试(){EventQueue.invokeLater(new Runnable() {@覆盖公共无效运行(){尝试 {UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());} 捕捉(ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex){ex.printStackTrace();}JFrame frame = new JFrame("Testing");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.add(new TestPane());框架.pack();frame.setLocationRelativeTo(null);frame.setVisible(true);}});}公共类 TestPane 扩展 JPanel {私有 BufferedImage 主控;私有 BufferedImage 旋转;公共TestPane(){尝试 {master = ImageIO.read(new File("/Volumes/Disk02/Dropbox/MegaTokyo/Miho_Small.png"));旋转 = rotateImageByDegrees(master, 0.0);} 捕捉(IOException ex){ex.printStackTrace();}定时器 timer = new Timer(40, new ActionListener() {私人双角= 0;私人双三角洲= 1.0;@覆盖公共无效actionPerformed(ActionEvent e){角度 += 增量;旋转 = rotateImageByDegrees(主,角度);重绘();}});计时器.start();}@覆盖公共维度 getPreferredSize() {返回大师==空?新维度(200, 200):新维度(master.getWidth(),master.getHeight());}@覆盖受保护的无效paintComponent(图形g){super.paintComponent(g);如果(旋转!= null){Graphics2D g2d = (Graphics2D) g.create();int x = (getWidth() - rotate.getWidth())/2;int y = (getHeight() - rotate.getHeight())/2;g2d.drawImage(旋转,x,y,这个);g2d.dispose();}}公共 BufferedImage rotateImageByDegrees(BufferedImage img,双角){双弧度 = Math.toRadians(角度);双罪 = Math.abs(Math.sin(rads)), cos = Math.abs(Math.cos(rads));int w = img.getWidth();int h = img.getHeight();int newWidth = (int) Math.floor(w * cos + h * sin);int newHeight = (int) Math.floor(h * cos + w * sin);BufferedImage 旋转 = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);Graphics2D g2d = 旋转的.createGraphics();AffineTransform at = new AffineTransform();at.translate((newWidth - w)/2, (newHeight - h)/2);整数 x = w/2;整数 y = h/2;at.rotate(rads, x, y);g2d.setTransform(at);g2d.drawImage(img, 0, 0, 这个);g2d.dispose();旋转返回;}}}
我可以生成类似...
I am trying to rotate a buffered image in java. Here is the code I am using:
public static BufferedImage rotate(BufferedImage bimg, double angle) { int w = bimg.getWidth(); int h = bimg.getHeight(); Graphics2D graphic = bimg.createGraphics(); graphic.rotate(Math.toRadians(angle), w / 2, h / 2); graphic.drawImage(bimg, null, 0, 0); graphic.dispose(); return bimg; }
I have looked a numerous stack overflow questions and answers on this topic and not been able to figure out why the image is chopped up the way it is when I try to rotate it. Here is an example showing a loaded image: loaded image
After I click the rotate button which calls the above function with the buffered image and a 90.0 for the angle: chopped up image
Can someone help me understand what is happening and how to fix it?
As always, the Internet to the rescue. So, this is some code which I hobbled together from other resources/post/blogs which will return a new image which is sized so it will contain the rotated image
public BufferedImage rotateImageByDegrees(BufferedImage img, double angle) { double rads = Math.toRadians(angle); double sin = Math.abs(Math.sin(rads)), cos = Math.abs(Math.cos(rads)); int w = img.getWidth(); int h = img.getHeight(); int newWidth = (int) Math.floor(w * cos + h * sin); int newHeight = (int) Math.floor(h * cos + w * sin); BufferedImage rotated = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = rotated.createGraphics(); AffineTransform at = new AffineTransform(); at.translate((newWidth - w) / 2, (newHeight - h) / 2); int x = w / 2; int y = h / 2; at.rotate(rads, x, y); g2d.setTransform(at); g2d.drawImage(img, 0, 0, this); g2d.setColor(Color.RED); g2d.drawRect(0, 0, newWidth - 1, newHeight - 1); g2d.dispose(); return rotated; }
Updated
So, using this PNG:
And this code...
package javaapplication1.pkg040; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; 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.Timer; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class Test { public static void main(String[] args) { new Test(); } public Test() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private BufferedImage master; private BufferedImage rotated; public TestPane() { try { master = ImageIO.read(new File("/Volumes/Disk02/Dropbox/MegaTokyo/Miho_Small.png")); rotated = rotateImageByDegrees(master, 0.0); } catch (IOException ex) { ex.printStackTrace(); } Timer timer = new Timer(40, new ActionListener() { private double angle = 0; private double delta = 1.0; @Override public void actionPerformed(ActionEvent e) { angle += delta; rotated = rotateImageByDegrees(master, angle); repaint(); } }); timer.start(); } @Override public Dimension getPreferredSize() { return master == null ? new Dimension(200, 200) : new Dimension(master.getWidth(), master.getHeight()); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (rotated != null) { Graphics2D g2d = (Graphics2D) g.create(); int x = (getWidth() - rotated.getWidth()) / 2; int y = (getHeight() - rotated.getHeight()) / 2; g2d.drawImage(rotated, x, y, this); g2d.dispose(); } } public BufferedImage rotateImageByDegrees(BufferedImage img, double angle) { double rads = Math.toRadians(angle); double sin = Math.abs(Math.sin(rads)), cos = Math.abs(Math.cos(rads)); int w = img.getWidth(); int h = img.getHeight(); int newWidth = (int) Math.floor(w * cos + h * sin); int newHeight = (int) Math.floor(h * cos + w * sin); BufferedImage rotated = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = rotated.createGraphics(); AffineTransform at = new AffineTransform(); at.translate((newWidth - w) / 2, (newHeight - h) / 2); int x = w / 2; int y = h / 2; at.rotate(rads, x, y); g2d.setTransform(at); g2d.drawImage(img, 0, 0, this); g2d.dispose(); return rotated; } } }
I can generate something like...
;