首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从TIFF图像数据创建TIFF文件

如何从TIFF图像数据创建TIFF文件
EN

Stack Overflow用户
提问于 2014-08-07 09:51:54
回答 2查看 2.7K关注 0票数 1

我有几个文件,其中包含一个特定的标题,后面跟着TIFF图像数据。如何将这些TIFF图像数据写入TIFF文件?谢谢你的帮助。

编辑:下面是我测试的内容:

代码语言:javascript
复制
InputStream is = new FileInputStream(filePath);
is.skip(252);
BufferedImage bufferedImage = ImageIO.read(is);
File fileOut = new File(fileOutPath);
ImageIO.write(bufferedImage,"TIFF", fileOut);

我跳过文件的特定头(252 bytes )以获得Tiff Image数据字节。但是bufferedImage是空的,所以我得到一个java.lang.IllegalArgumentException: im == null!异常。

在简历中,我有一个没有TIFF头的TIFF文件。TIFF头已被特定的头替换,但图像字节与TIFF文件中的图像字节完全相同。

编辑:多亏了haraldK,我终于可以创建一个TIFF头了。但我无法打开图像,可能是因为压缩:"M2 =修改的读代码II (MRII),即传真组4“。

下面是我创建的标题:

代码语言:javascript
复制
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 

在合并标头和图像数据之前,我应该解压缩图像数据吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-09 13:05:34

免责声明:这不是一个完全有效的例子(在这种情况下,我需要一些示例文件来验证),而是概述了这个想法。

首先,打开文件的流,跳过专有的头(您的代码假设您总是可以跳过任意数量的字节,但情况并不总是这样):

代码语言:javascript
复制
InputStream is = new FileInputStream(filePath);

int toSkip = 252;
int skipped = 0;

while (toSkip > 0 && (skipped = is.skip(toSkip)) >= 0) {
    toSkip -= skipped;
}

然后,根据TIFF规范重新创建一个有效的、最小的TIFF头。这其实并不难:

代码语言:javascript
复制
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream dataOut = new DataOutputStream(bytes);

dataOut.write('M');
dataOut.write('M');     // "Motorola" (network) byte order
dataOut.writeShort(42); // TIFF magic identifier (42)

dataOut.writeUnsignedInt(8); // Offset to 1st IFD

// ... write IFD, containing minimal info as per the spec

由于您的输入数据似乎是双层或黑白传真格式(参考)。注释),请参见规范中的两层图像(第17页)中所需的字段和允许的值。有关普通RGB图像,请参见第6节: RGB全色图像(第24页)。

注意,规范中的short在Java中是(无符号的) int,而LONG是(无符号的)int。还请注意,字段必须以增加的标签顺序写入。RATIONAL可以写成两个长(即两个未签名的ints)。对于XResolutionYResolution,只需编写72/1,因为这是默认的72 DPI。StripOffsets将是IFD +8的长度,用于在IFD之前写入的字节。如果没有条带,将RowsPerStrip设置为ImageLength,而StripByteCounts设置为整个(压缩)图像数据的长度。

对标头进行编码后,合并标头和图像数据,并读取它:

代码语言:javascript
复制
ByteArrayInputStream header = new ByteArrayInputStream(bytes.toByteArray());
InputStream stream = new SequenceInputStream(header, is); // Merge header and image data

现在,您可以读取图像:

代码语言:javascript
复制
BufferedImage image = ImageIO.read(stream); // Read image

// TODO: Test that image is non-null before attempting to write

但是,如果只将TIFF写回文件,则可以将数据从stream复制到新文件,并尝试在外部工具中打开它。这种方法比用Java解码图像并将其编码回TIFF (ImageIO不需要JAI或其他TIFF插件)要快得多,所需内存也更少:

代码语言:javascript
复制
OutputStream os = new FileOutputStream(new File(...));

byte[] buffer = new byte[1024];
int read;

while ((read = stream.read(buffer) >= 0) {
   os.write(0, read, buffer);
}
票数 0
EN

Stack Overflow用户

发布于 2014-08-07 10:32:39

您可以尝试使用这样的javax.imageio.ImageIO读/写操作:

代码语言:javascript
复制
ImageIO.write(img, "TIFF", new File('fileName'));

或者你可以使用Java高级成像API

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25179381

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档