java - 如何更改 ImageIO 写入字节顺序

标签 java tiff javax.imageio endianness

我正在使用

将 PDF 的 RenderedImage 写入 tiff 文件
javax.imageio.ImageIO.write(RenderedImage,"tif" ,file)

我希望我的 tiff 文件字节序是小端,但是它写的是大端,可以帮助解释如何将其更改为小端吗?

还可以解释为什么使用大端写入的数据比原始文件大小大吗? 我尝试在我的 Java 代码之外将数据转换为小端字节序,文件大小从 16 MB 大幅减少到 943 字节。

最佳答案

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();

关于java - 如何更改 ImageIO 写入字节顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44887355/

相关文章:

java - 更改 Java ImageIO 类的功能

java - 尝试创建一个文件来保存图像Java

java - 使用 Twelvemonkeys ImageIO 读取 TIFF ICC 配置文件

java - 如何在不使用抽象的情况下强制在子类中实现方法?

java - ActionScript 和 Java EE 中静态变量的区别

java - 在序列化中,将对象转换为字节流意味着什么?

java - 光栅图像的 sRGB IEC61966-2.1 ColorModel

java - 过滤图片的URL路径(img src)获取文件名

Java:如何知道 TIFF 图像是否为 Group4?

MATLAB tiff 文件格式与 PNG 文件格式。真正的无损压缩?