Affine Transform如何在此代码中运行?

时间:2023-02-09 10:58:45

The following code works correctly, but I'm having trouble understanding some of the details. Can somebody help me understand how the AffineTransform is working to rotate the image?

以下代码正常工作,但我无法理解一些细节。有人可以帮我理解AffineTransform如何旋转图像吗?

package pks;

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;

public class rotate {

    public static void main(String[] args) {
        new rotate();
    }

    public rotate() {
        EventQueue.invokeLater(new Runnable() {

           public void run() {

                final RotationPane rotationPane = new RotationPane(); // initilize object of RotationPane class
                JFrame frame = new JFrame("Test");

                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(rotationPane);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class RotationPane extends JPanel {

        private BufferedImage img;
        private BufferedImage rotated;

        private double angle;

        public RotationPane() {

            try {
                img = ImageIO.read(new File("C:\\Users\\pardeep\\Desktop\\tomb1.jpg")); // path of the image to be rotated
                setAngle(45);
            } 
            catch (IOException ex) {
            }

        }

        public void setAngle(double angle) {
            this.angle = angle;

            // Using Affine transform we will calculate the new values
            //x=vcos (theta)+wsin(theta)
            //y=vcos(theta)+ wsin(theta)

            double rads = Math.toRadians(angle);  // calculating angle in radian
            double sin = Math.abs(Math.sin(rads)),  //calculating sin theta
                   cos = Math.abs(Math.cos(rads)); // calculating cos theta

            int w = img.getWidth();
            int h = img.getHeight();

            int newWidth = (int) Math.floor(w * cos + h * sin);  //using affine transform
            int newHeight = (int) Math.floor(h * cos + w * sin);

            rotated = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);

            Graphics2D g2d = rotated.createGraphics(); //rotating planes.....

            AffineTransform plane = new AffineTransform();

            plane.translate((newWidth - w) / 2, (newHeight - h) / 2);

            int x=w/2;
            int y=h/2;

            plane.rotate(Math.toRadians(45), x, y);

            g2d.setTransform(plane);
            g2d.drawImage(img, 0, 0, this);
        }


        public Dimension getPreferredSize() {
            return  new Dimension(800,   // setting the window size
                              800);
        }

        protected void paintComponent(Graphics g) {
            // super.paintComponent(g); no need for it

            if (rotated != null) {   // drawing image on 2 dimentional size surface
                Graphics2D g2d = (Graphics2D) g.create(); 

                int x = (getWidth() - rotated.getWidth()) / 2;
                int y = (getHeight() - rotated.getHeight()) / 2;

                g2d.drawImage(rotated, x, y, this); // overriding the method......
            }
        }        
    }    
}

1 个解决方案

#1


What exactly don't you understand? plane.rotate(Math.toRadians(45), x, y); rotates the image around the center point clockwise by 45 degrees. plane.translate((newWidth - w) / 2, (newHeight - h) / 2); is the same as plane.translate(newWidth/2 - w/2, newHeight/2 - h/2); so it calculates the difference between the new center and the old center and moves the entire picture by that difference.

究竟你不明白什么? plane.rotate(Math.toRadians(45),x,y);将图像绕中心点顺时针旋转45度。 plane.translate((newWidth - w)/ 2,(newHeight - h)/ 2);与plane.translate相同(newWidth / 2 - w / 2,newHeight / 2 - h / 2);所以它计算新中心和旧中心之间的差异,并通过该差异移动整个图片。

I should mention that AffineTransform applies the transformations in the opposite order. So if you write this

我应该提到AffineTransform以相反的顺序应用转换。所以,如果你写这个

plane.translate((newWidth - w) / 2, (newHeight - h) / 2);
int x=w/2;
int y=h/2;
plane.rotate(Math.toRadians(45), x, y);

Then every pixel of of the image is first rotated by 45 degrees clockwise and then shifted, not the other way around. It's done this way because the transformations are supposed to be applied to the coordinate system. Applying transformation A followed by tranformation B to the coordinate system is mathematically equivalent to applying B followed by A to the pixels of the image.

然后,图像的每个像素首先顺时针旋转45度,然后移动,而不是相反。它是这样做的,因为转换应该应用于坐标系。将变换A后跟变换B应用于坐标系在数学上等效于将B后跟A应用于图像的像素。

#1


What exactly don't you understand? plane.rotate(Math.toRadians(45), x, y); rotates the image around the center point clockwise by 45 degrees. plane.translate((newWidth - w) / 2, (newHeight - h) / 2); is the same as plane.translate(newWidth/2 - w/2, newHeight/2 - h/2); so it calculates the difference between the new center and the old center and moves the entire picture by that difference.

究竟你不明白什么? plane.rotate(Math.toRadians(45),x,y);将图像绕中心点顺时针旋转45度。 plane.translate((newWidth - w)/ 2,(newHeight - h)/ 2);与plane.translate相同(newWidth / 2 - w / 2,newHeight / 2 - h / 2);所以它计算新中心和旧中心之间的差异,并通过该差异移动整个图片。

I should mention that AffineTransform applies the transformations in the opposite order. So if you write this

我应该提到AffineTransform以相反的顺序应用转换。所以,如果你写这个

plane.translate((newWidth - w) / 2, (newHeight - h) / 2);
int x=w/2;
int y=h/2;
plane.rotate(Math.toRadians(45), x, y);

Then every pixel of of the image is first rotated by 45 degrees clockwise and then shifted, not the other way around. It's done this way because the transformations are supposed to be applied to the coordinate system. Applying transformation A followed by tranformation B to the coordinate system is mathematically equivalent to applying B followed by A to the pixels of the image.

然后,图像的每个像素首先顺时针旋转45度,然后移动,而不是相反。它是这样做的,因为转换应该应用于坐标系。将变换A后跟变换B应用于坐标系在数学上等效于将B后跟A应用于图像的像素。