尝试压缩图像(Gzip + Jpeg),然后解压缩它们。

3

我试图压缩一系列png格式的图像。看起来压缩效果不错:

FileOutputStream fos = null;
GZIPOutputStream gzip = null;
fos = new FileOutputStream(PATH_SAVE_GZIP);
gzip = new GZIPOutputStream(fos);
for (int i = 0; i < NB_OF_IMAGES; i++) {
     BufferedImage im = images.get(i).getBufImg();
     ImageIO.write(im, "JPEG", gzip);  
}
gzip.finish();
gzip.close();
fos.close();

然而,当我尝试使用这段代码进行解压缩时,出现了空指针异常。我做错了什么?


没有堆栈跟踪。我只是检查bi是否为空,在BufferedImage bi = ImageIO.read(fin);之后。 - Vito Valov
看起来问题在于您将所有图像都写入一个GZIP流中,而在读取时不知道如何拆分,这是否适用于单个图像? - Aviram Segal
是的,它可以与单个一起使用。我认为这是因为ImageIO不会写入分隔符。因此,在读取时,它不知道何时完成一个图像并开始另一个。 - Vito Valov
在使用GZIP之前,您必须以某种方式将它们连接起来,或者只需使用ZIP,您可以为每个文件创建一个条目。 - Aviram Segal
我需要使用GZIP,这是必须的。如何执行? - Vito Valov
2个回答

3

我已经完成了我的项目,现在我知道答案了。这可以通过几种方式解决:

一种方法是使用ObjectOutput/Input Stream,并将BufferedImages写成对象。

另一种方法是使用ByteArrayOutputStream,并将图像写成字节。在使用之前,您应该知道要写入的大小。因此,我在每个图像之前写入大小来解决这个问题。虽然不是很高效,但有效。

        fileOutputStream fos = new FileOutputStream(path);
        GZIPOutputStream gzip = new GZIPOutputStream(fos);
        gzip.write(shortToBytes(numImatges));
        gzip.write(shortToBytes((short) 0));     
        for (int i = 0; i < dates.getNB_OF_IMAGES(); i++) {

            if (images != null) {
                im = images.get(i).getBufImg();
            }
            ByteArrayOutputStream byteOstream = new ByteArrayOutputStream();
            ImageIO.write(im, "jpeg", byteOstream);
            byteOstream.flush();
            byteOstream.close();
            gzip.write(shortToBytes((short) byteOstream.size()));
            gzip.write(byteOstream.toByteArray());


            }
//close streams

0

你的问题在于你将所有图像都写入了一个单一的 GZIP 流中,而在读取时,ImageIO 不知道一个图像何时结束,下一个图像何时开始。

你有两个选择:

  1. 使用 ZIP 而不是 GZIP
  2. 使用 jtarJava Tar Package 将文件打包成一个 TAR 文件,然后对 tar 进行 GZIP 压缩,在读取时,你需要先解压缩,然后从 tar 文件中提取图像。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接