使用ImageIO.write的质量损失

时间:2013-06-09 23:30:46

标签: image scala jpeg bufferedimage

我已经注意到使用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()

4 个答案:

答案 0 :(得分:10)

使用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 :(得分:1)

在Scala中,使用https://github.com/sksamuel/scrimage可以在jpegs上设置压缩级别

val in = // some input stream or byte array
val out = // some output stream etc
Image(in).writer(Format.JPEG).withCompression(1.0).write(out)

您可以为压缩级别设置0到1.0之间的任何值。

答案 2 :(得分:0)

jpeg图像正在使用有损压缩。 请改用png。这也是压缩的,但是使用无损算法。

答案 3 :(得分:0)

JPEG Cmpression是有损的。但PNG压缩是无损的。所以,我建议用png格式写。这意味着即使您使用PNG格式压缩,也不会损失质量。简单的线条:

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

但是,如果你想要jpg格式的质量,请将质量设置为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);