我有几个文件包含一个特定的 Headers 后跟TIFF图像数据 . 如何将这些TIFF图像数据写入TIFF文件?谢谢你的帮助 .
编辑:这是我测试的:
InputStream is = new FileInputStream(filePath);
is.skip(252);
BufferedImage bufferedImage = ImageIO.read(is);
File fileOut = new File(fileOutPath);
ImageIO.write(bufferedImage,"TIFF", fileOut);
我跳过文件的特定 Headers (252Bytes)来获取Tiff图像数据字节 . 但是bufferedImage为null所以我得到了一个java.lang.IllegalArgumentException:im == null!例外 .
在简历中,我有一个没有TIFF Headers 的TIFF文件 . TIFF标头已被特定标头替换,但图像字节与TIFF文件中的完全相同 .
编辑:感谢haraldK,我终于可以创建一个TIFF Headers . 但我无法打开图像,可能是因为压缩:“M2 =修改后的读码II(MRII),即传真组4” .
这是我创建的 Headers :
SubFileType (1 Long): Zero
ImageWidth (1 Long): 210
ImageLength (1 Long): 297
BitsPerSample (3 Short): 8, 8, 8
Compression (1 Short): Group 4 Fax (aka CCITT FAX4)
Photometric (1 Short): RGB
StripOffsets (1 Long): 306
SamplesPerPixel (1 Short): 3
RowsPerStrip (1 Short): 297
StripByteCounts (1 Long): 187110
ResolutionUnit (1 Short): None
XResolution (72 Rational):
YResolution (1 Rational): Unexpected numeric
DateTime (20 ASCII): 2014:07:12 10:51:51
Software (28 ASCII): Put your software name here
ImageDescription (30 ASCII): Put an image description here
我应该在合并 Headers 和图像数据之前解压缩图像数据吗?
2 回答
免责声明:这不是一个完全有效的例子(在这种情况下我需要一些示例文件来验证),而是概述了这个想法 .
首先,打开文件流,并跳过专有标头(您的代码假定您可以总是跳过您喜欢的字节数,但情况并非总是这样):
然后,根据TIFF specification重新创建有效的最小TIFF标头 . 这实际上并不太难:
由于您的输入数据似乎是双层或黑/白传真格式(参考注释),请参阅规范中的第3节:双层图像(第17页)以获取必填字段和允许值 . 有关普通RGB图像,请参阅第6节:RGB全彩色图像(第24页) .
请注意,规范中的SHORT在Java中是(unsigned)
short
,但LONG是(无符号)int
. 另请注意,必须按增加的标记顺序写入字段 . RATIONAL可以写成两个LONG(即两个未签名的int
s) . 对于XResolution
和YResolution
,只需写入72/1,因为这是默认的72 DPI .StripOffsets
将是在IFD之前写入的字节的IFD 8的长度 . 如果没有条带,则将RowsPerStrip
设置为等于ImageLength
和StripByteCounts
等于整个(压缩)图像数据的长度 .完成头部编码后,合并头部和图像数据,并读取它:
现在,您可以阅读图像:
但是,如果您只将TIFF写回文件,则可以将数据从
stream
复制到新文件,并尝试在外部工具中打开它 . 与在Java中解码图像,然后将其编码回TIFF(并且不需要用于ImageIO的JAI或其他TIFF插件)相比,这种方法将更快并且需要更少的内存:您可以尝试使用
javax.imageio.ImageIO
读/写操作,如下所示:或者你可以使用Java Advanced Imaging API .