任何图像格式的java图像压缩(jpg,PNG,gif)

时间:2015-02-10 18:32:31

标签: java

我正在使用下面给出的代码来进行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格式时; 它给我一个不支持压缩的错误。

那么我应该如何修改上面的代码以支持所有图像格式压缩

1 个答案:

答案 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这是它可以做的最好的事情。