【问题标题】:Rotating a BufferedImage causes it to change its position旋转 BufferedImage 会导致它改变位置
【发布时间】:2017-10-30 22:22:04
【问题描述】:

我正在尝试旋转一堆 BufferedImage 实例,旋转有效,但奇怪的是它们改变了位置。这是我如何做的一个简单的说明。

BufferedImage philo1=ImageIO.read(new File("D:\\philo1.png"));
public void paint(Graphics g)
{
    super.paint(g);
    Graphics2D g2d = (Graphics2D)g;
    AffineTransform old = g2d.getTransform();
    g2d.rotate(Math.toRadians(15),philo1.getWidth()/2,philo1.getHeight()/2);
    g.drawImage(philo1,172, 48, 50, 50,this);
    g2d.setTransform(old);
}

结果是这样的(有和没有旋转):

这可能是什么原因造成的?我怀疑原因是我在绘制图像时强制调整图像的大小,这就是为什么它在不同的位置绘制它,因为我在绘制之前调用了旋转方法。如果是这种情况,我该如何解决?

【问题讨论】:

  • 看起来是因为您正在通过角落引用图像。当你旋转它时,画布大小现在变大了。不是相对于角放置图像,而是相对于中心放置它。
  • 您不是在旋转图像,而是在旋转组件的整个 Graphics 上下文
  • 一个更好的解决方案是在它自己的上下文中旋转图像,对于example, something like this。这将生成一个新图像,根据您的需要旋转(和调整大小)

标签: java graphics rotation drawing image-resizing


【解决方案1】:

基本问题是,如果它是从上下文的左上角 (0x0) 绘制的,您正试图围绕图像的中心点旋转整个 Graphics 上下文,但图像是偏移量。

因为使用虚拟空间旋转图像非常有趣,所以我更喜欢生成一个在其自身上下文中旋转的新图像,然后简单地绘制它。对于example

如果这看起来工作量很大,那么您需要首先将Graphics 上下文翻译成上/左角是要绘制图像的位置,然后您就可以旋转图像围绕它的中心/锚点简单,例如:

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();
            }
        }

    }

}

注意:您也可以使用AffineTransform,但我只是保持简单

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-25
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多