Java 仿射变换在这段代码中是如何工作的?
下面的代码工作正常,但我在理解某些细节时遇到了困难。有人能帮我理解仿射变换是如何旋转图像的吗Java 仿射变换在这段代码中是如何工作的?,java,Java,下面的代码工作正常,但我在理解某些细节时遇到了困难。有人能帮我理解仿射变换是如何旋转图像的吗 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; impor
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......
}
}
}
}
你到底不明白什么<代码>平面。旋转(数学。托拉半径(45),x,y)代码>围绕中心点顺时针旋转图像45度<代码>平面平移((新宽度-w)/2,(新高度-h)/2)代码>与平面相同。平移(newWidth/2-w/2,newHeight/2-h/2)因此它计算新中心和旧中心之间的差异,并根据该差异移动整个图片 我应该提到仿射变换以相反的顺序应用变换。 所以如果你写这个
plane.translate((newWidth - w) / 2, (newHeight - h) / 2);
int x=w/2;
int y=h/2;
plane.rotate(Math.toRadians(45), x, y);
然后,图像的每个像素首先顺时针旋转45度,然后移动,而不是相反方向。这样做是因为变换应该应用于坐标系。将变换A和变换B应用于坐标系在数学上等同于将B和A应用于图像的像素。你知道A是什么吗?paintComponent方法在JPanel的中心绘制图像。为此,它计算JPanel中心和图像中心之间的差值,以确定在何处绘制它。但它已经使用g2d.drawImage绘制了图片(img,0,0,this);这个方法…那么我们为什么使用这个方法g2d.drawImage(旋转,x,y,这个)//在设置角度方法中,图像被绘制到另一个图像中,而不是屏幕上。