Вращающийся BufferedImage меняет свои цвета

Я пытаюсь кодировать класс, чтобы сшить вырезать изображения в направлении X и Y. Направление x работает, и чтобы уменьшить направление y, я подумал о том, чтобы просто повернуть изображение на 90° и запустить тот же код для уже масштабированного изображения (только в направлении x), а затем повернуть его обратно в исходное состояние.

Я нашел что-то с AffineTransform и попробовал это. Это фактически произвело повернутое изображение, но испортило цвета, и я не знаю почему.

Это весь код:

import java.awt.image.BufferedImage;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.io.File;
import java.io.IOException;
import javafx.scene.paint.Color;
import javax.imageio.ImageIO;


public class example {
/**
 * @param args the command line arguments
 */
public static void main(String[] args) throws IOException {
    // TODO code application logic here

    BufferedImage imgIn = ImageIO.read(new File("landscape.jpg"));
    BufferedImage imgIn2 = imgIn;

    AffineTransform tx = new AffineTransform();
    tx.rotate(Math.PI/2, imgIn2.getWidth() / 2, imgIn2.getHeight() / 2);//(radian,arbit_X,arbit_Y)

    AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
    BufferedImage last = op.filter(imgIn2, null);//(sourse,destination)
    ImageIO.write(last, "JPEG", new File("distortedColors.jpg"));
}

}

Просто измените имя файла в
BufferedImage imgIn = ImageIO.read(new File("landscape.jpg")); и попробуй это.

После выполнения вы получите 4 изображения: тепловую карту, изображение со швами и измененное изображение. Последнее изображение является тестом, чтобы увидеть, работает ли вращение, и оно должно показывать повернутое изображение, но с искаженными цветами...

Помощь будет принята с благодарностью!

РЕДАКТИРОВАТЬ:

введите описание изображения здесь

2 ответа

Решение

Кажется, что происходит преобразование цвета из-за прохождения null в op.filter(imgIn2, null);,

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

BufferedImage last = new BufferedImage( imgIn2.getWidth(), imgIn2.getHeight(), imgIn2.getType() );
op.filter(imgIn2, last );

Проблема с AffineTransformOp Тебе нужно:

AffineTransformOp.TYPE_NEAREST_NEIGHBOR

вместо билинейного у вас сейчас.

Второй абзац из документации намекает на это.

Этот класс использует аффинное преобразование для выполнения линейного отображения из двухмерных координат в исходном изображении или растра в двухмерные координаты в целевом изображении или растре. Тип используемой интерполяции задается через конструктор, либо объектом RenderingHints, либо одним из целочисленных типов интерполяции, определенных в этом классе. Если в конструкторе указан объект RenderingHints, подсказка интерполяции и подсказка качества визуализации используются для установки типа интерполяции для этой операции.

Подсказка по цветопередаче и сглаживание могут использоваться, когда требуется преобразование цвета. Обратите внимание, что должны соблюдаться следующие ограничения: источник и пункт назначения должны быть разными. Для растровых объектов количество полос в источнике должно быть равно количеству полос в месте назначения.

Так что это работает

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

Основываясь на том, что сказал бхавья...

Сохраняйте это простым, и вы должны использовать размеры, ожидаемые от операции:

AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
BufferedImage destinationImage = op.filter(bImage, op.createCompatibleDestImage(bImage, null));
Другие вопросы по тегам