Whispererli Whispererli - 7 months ago 47
Java Question

After transform image using AffineTransform, photo get low quality

I'm trying to fixing photo direction using EXIF information, the photo rotated correctly but after rotate they becomes very low quality...My guess is parameter passed during write new image is wrong. Any help appreciated.

Before
After

//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;
}

Answer

This may solve your problem. According to AffineTransformOp

"If destCM is null, an appropriate ColorModel is used; this ColorModel may 
have an alpha channel even if the source ColorModel is opaque."

Therefore I suggest the following:

AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BICUBIC);
BufferedImage destinationImage = op.createCompatibleDestImage(image,  null );
destinationImage = op.filter(image, null);
return destinationImage;

or even forgo the compatible image:

AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BICUBIC);
BufferedImage destinationImage = op.filter(image, null);
return destinationImage;

Also I'm not sure Bicubic is all that important but may not be the problem.

Comments