Ошибка смещения при повороте изображения с помощью AffineTransform Java - PullRequest
1 голос
/ 13 апреля 2019

Я пытаюсь повернуть изображение, используя класс 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 градусов вправо результат выглядит следующим образом:

result

1 Ответ

0 голосов
/ 23 апреля 2019

Вращение изображения с использованием AffineTransformOp (на мой взгляд) немного нелогично ... Само вращение легко, но, как вы, наверное, уже поняли, трудная часть корректно переводится, так что верхнийлевая часть изображения (или ограничивающая рамка, в случае поворота без квадранта) после поворота точно попадает в начало координат.

Если вам нужно повернуть на произвольный угол, выможно использовать следующий, довольно общий код:

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...