使用 AffineTransform 变换图像后,照片质量变差

After transform image using AffineTransform, photo get low quality

我正在尝试使用 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;
}

这可能会解决您的问题。根据 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;

我也不确定双三次是否那么重要,但可能不是问题所在。

因为兼容图像 returns 具有 alpha 的图像,即透明

这个

 Graphics2D g = destinationImage.createGraphics();
g.setBackground(Color.WHITE);
g.clearRect(0, 0, destinationImage.getWidth(), destinationImage.getHeight());

会在图片上加一层透明;之后绘制的图像与白色融合。

感谢大家的帮助:-) 将transform函数改成这样后,问题解决,不知道为什么会这样,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));