使用AffineTransform Java旋转图像时发生偏移错误
我正在尝试使用使用AffineTransform Java旋转图像时发生偏移错误,java,image-processing,Java,Image Processing,我正在尝试使用AffineTransform类旋转图像。但是,例如,当旋转90度时,图像会更改其宽度和高度值,从而导致我希望删除的偏移 这就是我尝试过的 OpRotate.java public BufferedImage filter(BufferedImage src, BufferedImage dest) { // Parameter auswerten float rotationAngle = ((float) attributes.getA
AffineTransform
类旋转图像。但是,例如,当旋转90度时,图像会更改其宽度和高度值,从而导致我希望删除的偏移
这就是我尝试过的
OpRotate.java
public BufferedImage filter(BufferedImage src, BufferedImage dest) {
// Parameter auswerten
float rotationAngle = ((float) attributes.getAttributeByName("Desired rotation angle").getValue());
AffineTransform rotationTransformation = new AffineTransform();
double middlePointX = src.getHeight() / 2;
double middlePointY = src.getWidth() / 2;
rotationTransformation.setToRotation(Math.toRadians(rotationAngle), middlePointX, middlePointY);
operation = new AffineTransformOp(rotationTransformation, AffineTransformOp.TYPE_BILINEAR);
return operation.filter(src, dest);
}
将图像向右旋转90度后,结果如下所示:
使用仿射变换器旋转图像(在我看来)有点违反直觉。。。旋转本身很容易,但正如您可能已经发现的那样,硬部分正在正确地平移,因此旋转后图像的左上部分(或者它的边界框,在非象限旋转的情况下)完全命中原点 如果需要旋转任意角度,可以使用以下非常通用的代码:
public static BufferedImage rotate(BufferedImage src, double degrees) {
double angle = toRadians(degrees); // Allows any angle
double sin = abs(sin(angle));
double cos = abs(cos(angle));
int width = src.getWidth();
int height = src.getHeight();
// Compute new width and height
double newWidth = width * cos + height * sin;
double newHeight = height * cos + width * sin;
// Build transform
AffineTransform transform = new AffineTransform();
transform.translate(newWidth / 2.0, newHeight / 2.0);
transform.rotate(angle);
transform.translate(-width / 2.0, -height / 2.0);
BufferedImageOp operation = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
return operation.filter(src, null);
}
但是,如果只希望旋转90度的倍数,可以使用此稍微快一点的变体:
public static BufferedImage rotate90(BufferedImage src, int quadrants) {
// Allows any multiple of 90 degree rotations (1, 2, 3)
int width = src.getWidth();
int height = src.getHeight();
// Compute new width and height
boolean swapXY = quadrants % 2 != 0;
int newWidth = swapXY ? height : width;
int newHeight = swapXY ? width : height;
// Build transform
AffineTransform transform = new AffineTransform();
transform.translate(newWidth / 2.0, newHeight / 2.0);
transform.quadrantRotate(quadrants);
transform.translate(-width / 2.0, -height / 2.0);
BufferedImageOp operation = new AffineTransformOp(transform, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); // 1:1 mapping
return operation.filter(src, null);
}
在我看来,使用仿射变换器旋转图像有点违反直觉。。。旋转本身很容易,但正如您可能已经发现的那样,硬部分正在正确地平移,因此旋转后图像的左上部分(或者它的边界框,在非象限旋转的情况下)完全命中原点 如果需要旋转任意角度,可以使用以下非常通用的代码:
public static BufferedImage rotate(BufferedImage src, double degrees) {
double angle = toRadians(degrees); // Allows any angle
double sin = abs(sin(angle));
double cos = abs(cos(angle));
int width = src.getWidth();
int height = src.getHeight();
// Compute new width and height
double newWidth = width * cos + height * sin;
double newHeight = height * cos + width * sin;
// Build transform
AffineTransform transform = new AffineTransform();
transform.translate(newWidth / 2.0, newHeight / 2.0);
transform.rotate(angle);
transform.translate(-width / 2.0, -height / 2.0);
BufferedImageOp operation = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
return operation.filter(src, null);
}
但是,如果只希望旋转90度的倍数,可以使用此稍微快一点的变体:
public static BufferedImage rotate90(BufferedImage src, int quadrants) {
// Allows any multiple of 90 degree rotations (1, 2, 3)
int width = src.getWidth();
int height = src.getHeight();
// Compute new width and height
boolean swapXY = quadrants % 2 != 0;
int newWidth = swapXY ? height : width;
int newHeight = swapXY ? width : height;
// Build transform
AffineTransform transform = new AffineTransform();
transform.translate(newWidth / 2.0, newHeight / 2.0);
transform.quadrantRotate(quadrants);
transform.translate(-width / 2.0, -height / 2.0);
BufferedImageOp operation = new AffineTransformOp(transform, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); // 1:1 mapping
return operation.filter(src, null);
}
检查AffineTransformOp页面-它在过滤器上显示偏移等-您想绘制图像的中心以查看发生了什么以及发生在哪里-您是否始终旋转90度(或90度的倍数)?或者你允许任意角度?检查AffineTransformOp页面-它在过滤器上说关于偏移等-你想画出图像的中心,看看发生了什么以及发生在哪里-你总是旋转90度(或90度的倍数)?或者你允许任意角度?