После преобразования изображения с помощью 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));
Другие вопросы по тегам