使用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度的倍数)?或者你允许任意角度?