当前位置: 首页 > 知识库问答 >
问题:

使用JAI(Java高级图像)压缩PNG

彭雨华
2023-03-14

我使用javax.imageioAPI和JAI来压缩不同类型的图像。它适用于JPEG使用JPEGImageWriter和GIF使用GIFImageWriter。但是它不支持使用PNGImageWriter进行PNG压缩,这会引发一个异常,如压缩类型未设置或“无有效压缩”等。所以我在下面使用了PNG的ImageWriter。它可以工作,但是图像质量太差了。

有人能建议如何使用PNGImageWriter进行PNG压缩,以及哪个JAR包含它吗?

File input = new File("test.png");

InputStream is = new FileInputStream(input);
BufferedImage image = ImageIO.read(is);

File compressedImageFile = new File(input.getName());

OutputStream os =new FileOutputStream(compressedImageFile);

Iterator<ImageWriter>writers = 
        ImageIO.getImageWritersByFormatName("jpg"); // here "png" does not work
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.5f);

writer.write(null, new IIOImage(image, null, null), param);

共有2个答案

东门晓博
2023-03-14

请检查此代码是否适用于您。

ImageWriteParam writeParam = writer.getDefaultWriteParam();

writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);

writeParam.setCompressionType("PackBits");

writeParam.setCompressionQuality(0.5f);

谢谢。

阎昌勋
2023-03-14

与JRE捆绑在一起的默认com.sun.imageio.plugins.png.PNGImageWriter似乎不支持设置压缩。这有点令人惊讶,因为这种格式显然支持压缩。然而,PNGImageWriter总是写压缩。

从它使用的源代码中可以看到:

Deflater def = new Deflater(Deflater.BEST_COMPRESSION);

这会给你很好的压缩,但是很慢。这对你来说可能已经足够好了,但是在某些情况下,使用更快的压缩和更大的文件可能更好。

要修复代码,使其可以与任何格式名称一起使用,请更改以下行:

ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(0.5f);

到:

ImageWriteParam param = writer.getDefaultWriteParam();

if (param.canWriteCompressed()) { 
    // NOTE: Any method named [set|get]Compression.* throws UnsupportedOperationException if false
    param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    param.setCompressionQuality(0.5f);
}

它仍然会写入压缩的PNG。

如果您需要对PNG压缩进行更多控制,比如设置压缩或使用过滤器,则需要找到支持它的ImageWriter。正如你提到的JAI,我认为clibngimagewriter是JAI imageio的一部分。jar或jai imageio工具。jar支持设置压缩。您只需查看ImageWriter的迭代器,查看是否已安装:

Iterator<ImageWriter>writers = ImageIO.getImageWritersByFormatName("png");
ImageWriter writer = null;

while (writers.hasNext()) {
    ImageWriter candidate = writers.next();

    if (candidate.getClass().getSimpleName().equals("CLibPNGImageWriter")) {
        writer = candidate; // This is the one we want
        break;
    }
    else if (writer == null) {
        writer = candidate; // Any writer is better than no writer ;-)
    }
}

使用正确的ImageWriter,代码应该可以正常工作。

 类似资料:
  • 我在试着读书。tiff图像。我知道我不能阅读ImageIO提供的tiff文件。阅读并了解JAI API的支持。tiff图片,但我不会使用JAI API。那么JAI API还有其他选择吗?我在哪里可以买到JAI API?

  • 从pagespeed中,我只获得了图像链接和可能的优化(以字节为单位) 例如,我有大小为300kb的图像,对于该图像,pagespeed显示100kb 这只是一个图像,但我相信我会有很多图像压缩。所以,我如何通过传递字节或百分比作为参数或使用java中的任何其他计算(通过使用API或图像处理工具)来压缩图像,以便获得google建议的图像压缩版本。 提前谢谢。

  • 我一直在计算图像的未压缩和压缩文件大小。这对我来说总是导致压缩图像比我预期的未压缩图像小。如果图像包含大量不同的颜色,则存储调色板会占用大量空间,还需要更多位来存储每个代码。然而,我的问题是,压缩方法是否可能导致比未压缩的RGB图像更大的文件。对于这种压缩方法仍然有用的、总共包含k种不同颜色的最小正方形RGB图像,其大小(像素)是多少?因此,我们想要找到,对于给定的k值,找到最小整数n,对于该整数

  • 通常没有必要改变这个对话框的设置,而且允许 WinRAR 自动选择优化参数是安全的。请注意不正确的使用这个对话框可能导致非常严重的运行和压缩损失,所以只有在您清楚您所作的时候,才能改变它的参数。 下面的这些设置大部分仅被 RAR 4.x 压缩格式支持。这些设置都不可用于 ZIP。只有 delta 压缩和 32 为可执行压缩可用于 RAR 5.0 压缩文件。 这个对话框包含下列选项。 文本压缩/(自

  • 问题内容: 寻找一种将图像压缩为pdf格式并输出pdf进行存档的方法。我无法在创建图像之前对其进行压缩,因为这会影响打印质量。 每个pdf的大小约为8MB,其中大部分由2张图片组成。图片为png格式,并在生成过程中转换为pdf(使用了第三方生成器) 有没有一种方法可以在不使用第3方工具的情况下用Java压缩它们。我尝试使用pdfbox,itext和第3方exe(neevia),第3方工具是迄今为止

  • 问题内容: 我正在通过wifi或移动网络通过网络发送图像,以将其存储在服务器中并再次检索。我已经这样做了,但是由于相机拍摄的图像太大,这使我的应用程序变慢,只是要指出我正在打开图库并从那里拍摄照片,而不是直接从应用程序拍摄照片。我注意到,从相机和图库中获取的来自whatsapp的图像已被压缩到大约50%。100kb。 目前,我的代码获取一个文件,并将其转换为字节,然后发送。这是获取文件并将其转换为