Вращающийся 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));