2017-06-27 127 views
0

我的应用程序负责使用特定的alghoritm将单个TIFF文件分割成多个较小的文件。一切正常,但我关心的是,应用程序生成的文件大小超过原始文件。图像压缩和ImageIO库

应用程序处理的原始文件总大小约为26mb,生成的文件总大小等于387mb!下面是一个过程的代码片段 - 我是一个图像压缩和ImageIO库的amator,并且一直没能找到任何有用的东西,因此我想问问是否有什么我可以改变的那些结果更接近。理想情况下,我想使用与原始相同的压缩。

final ImageWriter writer = ImageIO.getImageWritersByFormatName(resultsExtension).next(); 

    final ImageWriteParam writeParams = writer.getDefaultWriteParam(); 
    writeParams.setCompressionMode(ImageWriteParam.MODE_COPY_FROM_METADATA); 

    BufferedImage page = ImageUtils.getSinglePageFromTiffFile(documentToSplit, currentPageIndex); 

    while (currentPageIndex < pagesQty) { 

    OutputStream outStream = null; 
    ImageOutputStream imgOutStream = null; 

    try { 
     outStream = new FileOutputStream(newDocFile); 
     imgOutStream = ImageIO.createImageOutputStream(outStream); 

     writer.setOutput(imgOutStream); 
     writer.prepareWriteSequence(null); 

     writer.writeToSequence(new IIOImage(page, null, null), writeParams); 
     currentPageIndex++; 

     if (CONDITION) { 
      writer.endWriteSequence(); 
      break; 
     } 

     writer.writeToSequence(new IIOImage(page, null, null), writeParams); 
     currentPageIndex++; 
     } 

    } finally { 
     if (imgOutStream != null) { 
     imgOutStream.close(); 
     } 
     if (outStream != null) { 
     outStream.close(); 
     } 
    } 
    } 

getSinglePageFromTiffFile方法:

public static BufferedImage getSinglePageFromTiffFile(File file, int pageIndex) 
    throws IOException { 
ImageInputStream is = ImageIO.createImageInputStream(file); 
ImageReader reader; 
try { 
    reader = ImageIO.getImageReaders(is).next(); 
    reader.setInput(is); 
    return reader.read(pageIndex); 
} finally { 
    if (is != null) { 
    is.close(); 
    } 
} 

}

+1

如果您想将多页TIFF拆分为多个单页TIFF,您可能需要查看[this Q/A](https://stackoverflow.com/q/44565928/1428606),其中演示了如何执行这不需要解码图像,从而保持原始的压缩/文件大小。 – haraldK

回答

1

读你的代码,我解释如下:

在我看来,你是从你的源图像读取到的未压缩数据结构(BufferedImage)。这个数据结构似乎没有任何有关数据压缩的信息。

所以在你的写作逻辑中,你确实设置了“从输入图像复制压缩”(ImageWriteParam.MODE_COPY_FROM_METADATA)。由于读取的图像本身不具有任何压缩信息,因此图像数据应以未压缩格式写入。

使用压缩的输入图像和未压缩的输出图像,难怪单个图块的大小与输入文件相比更大。虽然这可能是可能的,但输入图像在被压缩的页面之间也存在冗余(我不知道TIFF足够说明这一点),但我认为它更可能是您正在编写未压缩的图像数据出。

+0

我已经发布了返回'BufferedImage'的方法。如何将有关原始文件压缩的​​信息传输到输出文件?有没有办法做到这一点?我不想降低原始图像的质量。 –

+0

ImagerReader :: getImageMetadata(int imageIndex)返回一个IIOMetadata。你可能可以在ImageWriter中使用它,但是我不知道该怎么做。 在您的项目中设置固定压缩值还是必须使用与输入文件中相同的值? – Ray