使用ImageIO.write会导致图像质量损失

7
我注意到使用ImageIO.write时存在显著的质量损失,我该如何禁用自动压缩?
val baos: ByteArrayOutputStream = new ByteArrayOutputStream
val newBi = new BufferedImage(img.getWidth, img.getHeight, BufferedImage.TYPE_INT_RGB)
val gr = newBi.createGraphics()
gr.drawImage(img, 0, 0, img.getWidth(), img.getHeight(), Color.WHITE, null)
ImageIO.write(newBi, "jpeg", baos)
val b = baos.toByteArray
baos.close()
3个回答

13

使用ImageWriter


ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next();
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // Needed see javadoc
param.setCompressionQuality(1.0F); // Highest quality
writer.write(image);

对于非照片图片,请使用 .png 格式。


正如 @PiotrekDe 的评论所说,以下内容似乎更合乎逻辑。

writer.write(null, new IIOImage(image, null, null), param)

1
我已经尝试了那些方法,但由于某些原因,输出图像被填充为黑色。你知道这可能是从哪里来的吗? - Roch
抱歉,我知道这些方法(以及png的速度慢),但通常我会选择png。 - Joop Eggen
2
我认为你需要将 param 传回给 writer,像这样:writer.write(null, new IIOImage(image, null, null), param) - omnomnom

2

JPEG压缩是有损的。但PNG压缩是无损的。因此,我建议使用PNG格式编写。这意味着即使您使用PNG格式压缩,也不会失去质量。简单来说:

ImageIO.write(newBI,"png",someOutputStream);

但是,如果你想要以jpg格式保存并保持高质量,需要将Quality设置为100%。以下代码可能会对你有所帮助。

    ImageWriter jpgWriter = ImageIO.getImageWritersByFormatName("jpg").next();
    ImageWriteParam jpgWriteParam = jpgWriter.getDefaultWriteParam();
    jpgWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    jpgWriteParam.setCompressionQuality(1f);
    jpgWriter.setOutput(someOutputStream);
     //better to use ImageOutputStream
    jpgWriter.write(null,new IIOImage(yourImage, null, null), jpgWriteParam);

0

JPEG 图像使用有损压缩。建议使用 PNG 替代。PNG 也是压缩的,但采用无损算法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接