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

标签 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("png"); 来获取 PNG 格式时; 它给我错误,表示不支持压缩。

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

最佳答案

您的代码的问题是您使用了 ImageWriter.getDefaultWriteParam()。来自 ImageWriter.java 的以下引用:

public ImageWriteParam getDefaultWriteParam()

Returns a new ImageWriteParam object of the appropriate type for this file format containing default values, that is, those values that would be used if no ImageWriteParam object were specified. This is useful as a starting point for tweaking just a few parameters and otherwise leaving the default settings alone.

The default implementation constructs and returns a new ImageWriteParam object that does not allow tiling, progressive encoding, or compression, and that will be localized for the current Locale (i.e., what you would get by calling new ImageWriteParam(getLocale()).

Individual plug-ins may return an instance of ImageWriteParam with additional optional features enabled, or they may return an instance of a plug-in specific subclass of ImageWriteParam.

实际行为取决于特定 ImageWriteParam 的单独实现。我相信 JPG 图像起作用的原因是 JPG 的 ImageWriteParam 为默认 ImageWriteParam 设置了 canWriteCompressed protected 字段,但对于 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 插件具有固定过滤 - 自适应过滤和固定放气级别 - 9,这是它能做的最好的事情。

关于java图像压缩任何图像格式(jpg,PNG,gif),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28439136/

相关文章:

java - 一旦我点击屏幕上的某个地方,菜单按钮就会消失

java - java fork-join 框架如何将任务分配到处理器上?

java - 从类文件访问属性文件或静态常量是否更快?

java - 从 XSD 模式生成 JAXB 类会导致奇怪的包结构

java - 用于带缓存的流媒体播放器

Java 构建路径错误 - 无法读取(项目)中的(库)或者不是 Eclipse 中的有效 zip 文件

java - 在 Java 中转发 HTTP 请求

java - 执行PreparedStatement select失败

java - 在 Android 中使用 AccountManager 的好教程?

java - Spark NotSerializableException