我正在使用下面给出的代码对jpeg图像进行图像压缩。
File input = new File("digital_image_processing.jpg");
BufferedImage image = ImageIO.read(input);
File compressedImageFile = new File("compress.jpg");
OutputStream os = new FileOutputStream(compressedImageFile);
Iterator<ImageWriter>writers = ImageIO.getImageWritersByFormatName("jpg");
ImageWriter writer = (ImageWriter) writers.next();
ImageOutputStream ios = ImageIO.createImageOutputStream(os);
writer.setOutput(ios);
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(0.05f);
writer.write(null, new IIOImage(image, null, null), param);
但是当我尝试通过更改ImageIO.getImageWritersByFormatName(“ png”)获得PNG格式时;
它给我的错误是不支持压缩。
那么我应该如何修改上面的代码,以支持所有图像格式压缩
最佳答案
代码的问题是您使用了ImageWriter.getDefaultWriteParam()。从ImageWriter.java的以下引用中:
公共ImageWriteParam getDefaultWriteParam()
返回与此类型合适的新ImageWriteParam对象
包含默认值的文件格式,即默认值
如果未指定ImageWriteParam对象,则将使用此参数。这是
可以用作调整一些参数的起点,并且
否则,将保留默认设置。
默认实现构造并返回一个新的
不允许平铺的ImageWriteParam对象,渐进式
编码或压缩,并且将针对当前
区域设置(即致电new会得到什么
ImageWriteParam(getLocale())。
各个插件可能会返回ImageWriteParam的实例,其中包含
启用了其他可选功能,否则它们可能会返回一个实例
ImageWriteParam的特定于插件的子类。
实际行为取决于特定ImageWriteParam的单独实现。我相信JPG图像起作用的原因是JPG的ImageWriteParam为默认的ImageWriteParam设置了canWriteCompressed
受保护的字段,但为PNG图像设置了受保护的字段,出于某种原因,它不这样做。
如果查看com.sun.imageio.plugins.png.PNGImageWriteParam.java,您会发现它确实没有设置它。
为了使您的代码正常工作,您可以这样做:
File input = new File("digital_image_processing.jpg");
BufferedImage image = ImageIO.read(input);
File compressedImageFile = new File("compress.jpg");
OutputStream os = new FileOutputStream(compressedImageFile);
Iterator<ImageWriter>writers = ImageIO.getImageWritersByFormatName("jpg");
ImageWriter writer = (ImageWriter) writers.next();
ImageOutputStream ios = ImageIO.createImageOutputStream(os);
writer.setOutput(ios);
ImageWriteParam param = writer.getDefaultWriteParam();
// Check if canWriteCompressed is true
if(param.canWriteCompressed()) {
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(0.05f);
}
// End of check
writer.write(null, new IIOImage(image, null, null), param);
更新:我正在尝试为您提供一种在ImageIO框架内微调PNG图像压缩的方法。但是不幸的是,考虑到当前的实现,这似乎几乎是不可能的。 Java PNG writer插件具有固定的过滤-自适应过滤和固定的deflater级别-9,这是它可以做的最好的事情。