Вопрос по java – AffineTransform усекает изображение

1

У меня есть изображение, и я должен повернуть его на 45, 90, 135, 180 градусов. Что я делаю:

&l#;code&g#;#ry {
    BufferedImage src = ImageIO.read(new File("src.png"));
    double ang = Ma#h.#oRadians(90);

    AffineTransform # = new AffineTransform();
    #.se#ToRo#a#ion(ang, src.ge#Wid#h() / 2, src.ge#Heigh#() / 2);

    AffineTransformOp op = new AffineTransformOp(#, null);
    BufferedImage ds# = new BufferedImage(src.ge#Wid#h(), src.ge#Heigh#(), src.ge#Type());
    op.fil#er(src, ds#);

    ImageIO.wri#e(ds#, "png", new File("ou#pu#.png"));
} ca#ch(Excep#ion ex) { ex.prin#S#ackTrace();
}
&l#;/code&g#;

Проблема заключается в том, что изображение меняет свою позицию и выходит за пределы целевого изображения:

Проблема h##p://img32.imageshack.us/img32/3328/resul#cs.png

Я гуглил это и нашел решение в этом вопросе:AffineTransform обрезает изображение, что я не так делаю? Но я совершенно не понимаю этого, и он работает только для квадрантов. Я пытался умножить вдвое ширину и высоту пункта назначения, но это не удалось:

Еще один сбой h##p://img401.imageshack.us/img401/2417/resul#2a.png

Как это исправить? Изображение назначения не должно иметь каких-либо дополнительных (кроме необходимых для диагонального вращения) пробелов или усеченной области. Угловые проблемы (0 == 180 или по часовой стрелке) не важны.

Спасибо за любую помощь.

У меня есть пример и фотографии, которые иллюстрируют проблему. Код готов к запуску. Cenius
Как насчет дополнительного пространства по диагонали в 45 и 135? Должно ли оно быть прозрачным? 180 идентичен 0? Пожалуйста, измените ваш вопрос, чтобы включитьsscce которая демонстрирует проблему, которую вы описываете.FauxImage может быть удобным дополнением. trashgod

Ваш Ответ

2   ответа
4

Edit: Now it works for the general case.

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

Я изменил ваш код для преобразования прямоугольника исходного изображения, чтобы мы могли легко получить новые размеры / смещение изображения. Это используется, чтобы построить пункт назначенияBufferedImage правильных размеров, и добавить перевод к вашемуAffineTransform таким образом, центр изображения располагается в центре целевого изображения.

        BufferedImage src = ImageIO.read(new File(INPUT));
        int w = src.getWidth();
        int h = src.getHeight();

        AffineTransform t = new AffineTransform();
        double ang = Math.toRadians(35);
        t.setToRotation(ang, w / 2d, h / 2d);

        // source image rectangle
        Point[] points = {
            new Point(0, 0),
            new Point(w, 0),
            new Point(w, h),
            new Point(0, h)
        };

        // transform to destination rectangle
        t.transform(points, 0, points, 0, 4);

        // get destination rectangle bounding box
        Point min = new Point(points[0]);
        Point max = new Point(points[0]);
        for (int i = 1, n = points.length; i < n; i ++) {
            Point p = points[i];
            double pX = p.getX(), pY = p.getY();

            // update min/max x
            if (pX < min.getX()) min.setLocation(pX, min.getY());
            if (pX > max.getX()) max.setLocation(pX, max.getY());

            // update min/max y
            if (pY < min.getY()) min.setLocation(min.getX(), pY);
            if (pY > max.getY()) max.setLocation(max.getX(), pY);
        }

        // determine new width, height
        w = (int) (max.getX() - min.getX());
        h = (int) (max.getY() - min.getY());

        // determine required translation
        double tx = min.getX();
        double ty = min.getY();

        // append required translation
        AffineTransform translation = new AffineTransform();
        translation.translate(-tx, -ty);
        t.preConcatenate(translation);

        AffineTransformOp op = new AffineTransformOp(t, null);
        BufferedImage dst = new BufferedImage(w, h, src.getType());
        op.filter(src, dst);

        ImageIO.write(dst, "png", new File(OUTPUT));
Есть шанс, что ты превратишь это вSSCCE? Есть некоторыеimages at my site на который вы можете сделать горячую ссылку для исходного изображения.
0

AffineTransformOp op = new AffineTransformOp(t, null);

с

AffineTransformOp op = new AffineTransformOp(t,  AffineTransformOp.TYPE_BILINEAR);

Это значительно улучшит качество продукции.

@MuhammedRefaat Пожалуйста, прочитайте ссылку в комментарии выше. Правила сообщества заключаются в том, что мы не удаляем из обзора вещи, которые являются попытками ответить. Конечно, вы можете тратить свои отрицательные голоса и удалять голоса, когда вы достигаете 20 КБ, как вы хотите. Просто не используйте обзор, чтобы удалить их.
@MuhammedRefaat Как это не пытается дать ответ? Это может быть совершенно неправильно,but that doesn't mean we should abuse the review queues to delete it.
Это не дает ответа на вопрос. Чтобы критиковать или запросить разъяснения у автора, оставьте комментарий под его постом - вы всегда можете прокомментировать свои собственные посты, и как только у вас будет достаточноreputation Вы сможетеcomment on any post. - From Review
Пожалуйста, четко укажите, какой строки по содержанию ...
@ Я всегда верю, что предложения следует размещать в качестве комментариев, если каждое предложение, написанное как ответ, физически будет иметь около 10 ответов, а логически - только 2, я просто пытаюсь подчиняться правилам сообщества.

Похожие вопросы