2017-07-03 40 views
1

我写PDF的RenderedImage的使用如何改变的ImageIO写字节序

javax.imageio.ImageIO.write(RenderedImage,"tif" ,file) 

林希望我的TIFF文件端TIFF文件是little-endian的,但是它在大端写道,可以帮助解释如何将其改为小端?

也可以解释为什么使用big-endian编写的数据比原始文件大小更大吗? 我试图将数据转换为我的Java代码之外的小端,并且文件大小从16 MB大幅降低到943字节。

+0

这TIFF插件的ImageIO您使用的?使用(my)TwelveMonkeys插件,您可以使用'stream.setByteOrder(LITTLE_ENDIAN)'简单地设置'ImageInputStream'的字节顺序(字节顺序)。它还支持使用传递给['ImageWriter.write(...)'](https://docs.oracle.com/javase/7/docs/api/javax/imageio/ImageWriter)的流元数据设置字节顺序。 HTML#写(javax.imageio.metadata.IIOMetadata中,%20javax.imageio.IIOImage,%20javax.imageio.ImageWriteParam))。这种方式也适用于JAI。但是,我相信如果你看到这样的尺寸减小是完全错误的...... – haraldK

+0

Im使用TwelveMonkeys插件,谢谢你的建议,我能够设置Endianness,但是我仍然有设置压缩的问题,可以使用相同的插件在tiff上设置压缩?以及如何做到这一点?我想这就是文件大小更大的原因。 – Vinoth

回答

2

ImageIO API没有指定字节顺序(字节顺序)的标准方式。如何做到这一点,或者它是否受支持,都取决于插件。

对于TIFF格式,存在多个插件(JAI,GeoTIFF,TwelveMonkeys,JDK9)。所有提到的插件(据我所知)支持使用发送到ImageWriter.write(...)的流元数据来设置字节序。字节顺序是您可以在TIFF流元数据中设置的唯一字段。

ImageWriter writer = ImageIO.getImageWritersByFormatName("TIFF").next(); 
writer.setOutput(stream); 

IIOMetadata streamMetadata = writer.getDefaultStreamMetadata(); 

IIOMetadataNode root = new IIOMetadataNode("com_sun_media_imageio_plugins_tiff_stream_1.0"); 
IIOMetadataNode byteOrder = new IIOMetadataNode("ByteOrder"); 
byteOrder.setAttribute("value", order == LITTLE_ENDIAN ? "LITTLE_ENDIAN" : "BIG_ENDIAN"); 
root.appendChild(byteOrder); 

streamMetadata .mergeTree("com_sun_media_imageio_plugins_tiff_stream_1.0", root); 

// ... 

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

此外,如果使用的是流元数据没有指定,TwelveMonkeys TIFF插件将使用来自ImageOutputStream正在写入的字节顺序。以这种方式指定字节顺序在我看来更直接,但是插件之间的兼容性明显较差。

try (ImageOutputStream stream = ImageIO.createImageOutputStream(out)) { 
    stream.setByteOrder(ByteOrder.LITTLE_ENDIAN); 

    ImageIO.write(image, "TIFF", stream); 
} 

关于文件的大小,最知名的TIFF插件默认会写未压缩的图像数据。不幸的是,没有办法直接使用ImageIO便捷方法指定压缩设置,所以使用这些方法编写的任何TIFF都将被解压缩。

ImageIO API反而要求您获取要写入的格式的ImageWriter,并传入ImageWriteParam以指定压缩设置。请注意,支持的压缩类型可能因插件而异。另请注意,哪种压缩类型能够产生最佳压缩率,取决于您要压缩的图像数据。

ImageWriter writer = ImageIO.getImageWritersByFormatName("TIFF").next(); 
writer.setOutput(stream); 

ImageWriteParam param = writer.getDefaultWriteParam(); 
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 
param.setCompressionType("LZW"); // "Zlib", "PackBits", "JPEG", "CCITT T.4", "CCITT T.6" etc. 
param.setCompressionQuality(0.5f); // Applies only to some compression types. Generally: 
            // * 0.0 means highest compression 
            // * 1.0 means best quality 

可以查询当前插件什么的压缩类型可供选择,采用:

String[] types = param.getCompressionTypes();