Поворот изображения Java с помощью AffineTransform выводит черное изображение, но хорошо работает при изменении размера - PullRequest
5 голосов
/ 17 марта 2012

Я просто пытаюсь повернуть файл JPG на 90 градусов. Однако мой код выводит изображение (BufferedImage), которое полностью черное.

Вот способ воспроизведения: (Скачать 3.jpg здесь )

private static BufferedImage transform(BufferedImage originalImage) {
    BufferedImage newImage = null;
    AffineTransform tx = new AffineTransform();
    tx.rotate(Math.PI / 2, originalImage.getWidth() / 2, originalImage.getHeight() / 2);

    AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BICUBIC);
    newImage = op.filter(originalImage, newImage);

    return newImage;
}

public static void main(String[] args) throws Exception {
    BufferedImage bi = transform(ImageIO.read(new File(
            "3.jpg")));
    ImageIO.write(bi, "jpg", new File("out.jpg"));

}

Что здесь не так?

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

Ответы [ 2 ]

14 голосов
/ 17 марта 2012

Передача нового BufferedImage в метод filter () вместо того, чтобы позволять ему создавать свои собственные работы (не полностью черные).

Кроме того, преобразование не работает должным образом, в конечном итоге изображение смещено в месте назначения. Мне удалось это исправить, вручную применив необходимые переводы, отметив эти работы в обратном порядке, и на целевом изображении ширина = старая высота, а высота = старая ширина.

AffineTransform tx = new AffineTransform();

// last, width = height and height = width :)
tx.translate(originalImage.getHeight() / 2,originalImage.getWidth() / 2);
tx.rotate(Math.PI / 2);
// first - center image at the origin so rotate works OK
tx.translate(-originalImage.getWidth() / 2,-originalImage.getHeight() / 2);

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

// new destination image where height = width and width = height.
BufferedImage newImage =new BufferedImage(originalImage.getHeight(), originalImage.getWidth(), originalImage.getType());
op.filter(originalImage, newImage);

Javadoc для filter () утверждает, что он создаст BufferedImage для вас, я все еще не уверен, почему это не работает, здесь должна быть проблема.

 If the destination image is null, a BufferedImage is created with the source ColorModel.
5 голосов
/ 19 марта 2012

Если вы были открыты к идее использования сторонних библиотек (очень маленьких, всего 2 класса), то imgscalr может сделать это за вас в одной строке, работая над всеми фильтрами, полученными на этом другом изображении. типы могут быть причиной.

Использование Scalr.rotate (...) будет выглядеть примерно так:

BufferedImage newImage = Scalr.rotate(originalImage, Rotation.CW_90);

Если этот поворот является частью более крупного приложения, которое обрабатывает изображения, вы можете даже сделать это асинхронно, если вам это нужно ( AsyncScalr class ).

imgscalr находится под лицензией Apache 2, и все источники доступны; если вы предпочитаете делать это вручную, прочитайте код для метода rotate () , я задокументировал все ошибки, которые могут возникнуть при работе с фильтрами в Java2D.

Надеюсь, это поможет!

...