java 任何图像格式的java图像压缩(jpg,PNG,gif)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28439136/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java image compression for any image format(jpg, PNG, gif)
提问by
I am using the code given below for image compression of jpeg image.
我正在使用下面给出的代码对 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);
But when I tried for for PNG format by changing ImageIO.getImageWritersByFormatName("png"); It is giving me error that compression not supported.
但是当我通过更改 ImageIO.getImageWritersByFormatName("png"); 来尝试 PNG 格式时;它给了我不支持压缩的错误。
So how should i modify the above code so as to support all image format compression
那么我应该如何修改上面的代码以支持所有图像格式压缩
采纳答案by dragon66
The problem with your code is that you used ImageWriter.getDefaultWriteParam(). From the following quote from ImageWriter.java:
您的代码的问题在于您使用了 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 getDefaultWriteParam()
返回此文件格式的适当类型的新 ImageWriteParam 对象,其中包含默认值,即在未指定 ImageWriteParam 对象时将使用的那些值。这作为调整几个参数的起点非常有用,否则保留默认设置。
默认实现构造并返回一个新的 ImageWriteParam 对象,该对象不允许平铺、渐进式编码或压缩,并且将针对当前区域设置进行本地化(即,您将通过调用 new ImageWriteParam(getLocale()) 获得的内容)。
个别插件可能会返回一个 ImageWriteParam 的实例并启用附加的可选功能,或者它们可能会返回一个特定于插件的 ImageWriteParam 子类的实例。
The actual behavior depends on individual implementation of specific ImageWriteParam. I believe the reason JPG image works is that the ImageWriteParam for JPG set the canWriteCompressed
protected field for the default ImageWriteParam but for PNG image, for some reason it doesn't do that.
实际行为取决于特定 ImageWriteParam 的个别实现。我相信 JPG 图像有效的原因是 JPG 的 ImageWriteParam 为canWriteCompressed
默认的 ImageWriteParam设置了受保护的字段,但对于 PNG 图像,由于某种原因它没有这样做。
If you look at the com.sun.imageio.plugins.png.PNGImageWriteParam.java, you will find it indeed doesn't set it.
如果你查看com.sun.imageio.plugins.png.PNGImageWriteParam.java,你会发现它确实没有设置它。
In order to make your code work generally, you can do like this:
为了使您的代码正常工作,您可以这样做:
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);
Update:I was trying to find out a way for you to fine-tune PNG image compression within the framework of ImageIO. But unfortunately, given the current implementation, it seems next to impossible. Java PNG writer plugin has fixed filtering - adaptive filtering and fixed deflater level - 9 which is the best thing it could do.
更新:我试图找到一种方法让您在 ImageIO 框架内微调 PNG 图像压缩。但不幸的是,鉴于目前的实施,这似乎几乎是不可能的。Java PNG 编写器插件具有固定过滤 - 自适应过滤和固定 deflater 级别 - 9,这是它可以做的最好的事情。