我正在使用下面给出的代码来进行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(&#34; png&#34;)来尝试PNG格式时; 它给我一个不支持压缩的错误。
那么我应该如何修改上面的代码以支持所有图像格式压缩
答案 0 :(得分:1)
您的代码的问题在于您使用了ImageWriter.getDefaultWriteParam()。来自ImageWriter.java的以下引用:
public 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编写器插件具有固定的过滤 - 自适应过滤和固定的deflater级别 - 9这是它可以做的最好的事情。