0

这段代码有什么理由会改变原始JPEG的分辨率?我可以理解文件大小是否不同,因为 JPEG 质量设置可能不同,但我不明白为什么这会调整图像大小。

File newfile=new File(mydestinationfolder.concat(imagename));
Files.move(file.toPath(),newfile.toPath(), REPLACE_EXISTING);
Rotation Orientation;
if ((Orientation=Exif_data.get_Exif_Orientation(newfile)) != null) {

    System.out.println(Orientation.toString());
    BufferedImage oldimage = ImageIO.read(newfile);
    BufferedImage tmp = Scalr.rotate(oldimage, Orientation);
    oldimage.flush();
    oldimage=tmp;
    ImageIO.write(oldimage, "JPEG", newfile);

}
4

2 回答 2

1

好吧,我不确定为什么,但 ImageIO.write() 的默认设置正在改变分辨率。如果我定义一个 JPEG 质量设置为 100% 的自定义写入器,则图像分辨率保持不变。

注意:最后的 output.close() 很重要,因为只要流打开,文件就会被锁定。

BufferedImage oldimage = ImageIO.read(newfile);
BufferedImage tmp = Scalr.rotate(oldimage, Orientation);
oldimage.flush();
oldimage=tmp;
Iterator iter = ImageIO.getImageWritersByFormatName("jpeg");
ImageWriter writer = (ImageWriter)iter.next();
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
float quality=1.0f;
iwp.setCompressionQuality(quality);

FileImageOutputStream output = new FileImageOutputStream(newfile);
writer.setOutput(output);

IIOImage image = new IIOImage(oldimage, null, null);
writer.write(null, image, iwp);
writer.dispose();
output.close();
于 2013-06-11T18:53:25.917 回答
1

迟到的答案,但无论如何..

由于使用 ImageIO 的 JPEG 读取/操作/写入循环总是有损的,并且您所做的只是旋转,因此您应该查看来自 mediautil 的LLJTran,如该线程中所述。

使用该软件包,您应该能够从 JPEG 块压缩的特殊功能中受益,以进行无损 JPEG 转换。

仍然不明白为什么您的原始代码会改变图像分辨率,也不明白为什么您提出的解决方案会修复它……对我来说听起来像是一个错误,应该报告给 Oracle。但我所知道的是,将 JPEG 质量设置为 1.0 (100%) 并不是 JPEG 的本意,并且会导致巨大的文件质量没有提高(它可能比以质量存储更糟糕)原始的)给定输入已经是压缩的 JPEG 。

于 2013-06-16T17:39:25.093 回答