После преобразования изображения с помощью AffineTransform фотография получится низкого качества
Я пытаюсь определить направление фотографии, используя информацию EXIF, фотография поворачивается правильно, но после поворота они становятся очень низкого качества... Я предполагаю, что параметр, переданный во время записи нового изображения, неверен. Любая помощь приветствуется.
//code get Exif information
Metadata metadata = ImageMetadataReader.readMetadata(outputFile);
Directory directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
if(directory == null) {
logger.warn("no EXIF info.");
outputFile.delete();
return;
}
JpegDirectory jpegDirectory = metadata.getFirstDirectoryOfType(JpegDirectory.class);
int orientation;
try {
orientation = directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
if(orientation != 1) {
//rotate image
int w = jpegDirectory.getImageWidth();
int h = jpegDirectory.getImageHeight();
ImageInformation imageInformation = new ImageInformation(orientation, w, h);
AffineTransform affineTransform = getExifTransformation(imageInformation);
InputStream pictureStream = new FileInputStream(outputFile);
BufferedImage pictureBuffer = ImageIO.read(pictureStream);
pictureStream.close();
if (pictureBuffer == null) {
logger.warn("The picture buffer parsed is null.");
}
pictureBuffer = transformImage(pictureBuffer, affineTransform);
//code do image transfer
public static BufferedImage transformImage(BufferedImage image, AffineTransform transform) throws Exception {
AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BICUBIC);
BufferedImage destinationImage = op.createCompatibleDestImage(image, null );
Graphics2D g = destinationImage.createGraphics();
g.setBackground(Color.WHITE);
g.clearRect(0, 0, destinationImage.getWidth(), destinationImage.getHeight());
destinationImage = op.filter(image, destinationImage);
return destinationImage;
}
2 ответа
Это может решить вашу проблему. По данным AffineTransformOp
"If destCM is null, an appropriate ColorModel is used; this ColorModel may
have an alpha channel even if the source ColorModel is opaque."
Поэтому я предлагаю следующее:
AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BICUBIC);
BufferedImage destinationImage = op.createCompatibleDestImage(image, null );
destinationImage = op.filter(image, null);
return destinationImage;
или даже отказаться от совместимого изображения:
AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BICUBIC);
BufferedImage destinationImage = op.filter(image, null);
return destinationImage;
Также я не уверен, что Bicubic так важен, но проблема не в этом.
Поскольку совместимое изображение возвращает изображение с альфа-каналом, т.е. прозрачным
этот
Graphics2D g = destinationImage.createGraphics();
g.setBackground(Color.WHITE);
g.clearRect(0, 0, destinationImage.getWidth(), destinationImage.getHeight());
нанесет слой прозрачности на изображение; изображение, нарисованное впоследствии, будет слито с белым цветом.
Спасибо всем за помощь:-) После изменения функции преобразования в эту, проблема решена, не уверен, почему это так, gpasch может быть прав
public static BufferedImage transformImage(BufferedImage image, AffineTransform transform) throws Exception {
AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BICUBIC);
BufferedImage destinationImage = new BufferedImage(image.getWidth(),image.getHeight(), image.getType());
destinationImage = op.filter(image, destinationImage);
return destinationImage;
}
Сохраняйте это простым, и вы должны использовать размеры, ожидаемые от операции:
AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
BufferedImage destinationImage = op.filter(bImage, op.createCompatibleDestImage(bImage, null));