我的主要目的是将多个不同的tiff图像文件合并到一个文件中。我有一个使用TwelveMonkeys库的工作代码。现在,我希望使用默认的java库来实现相同的目标。我准备了一个小代码示例来调试和发现问题。
public static ByteArrayOutputStream mergeIntoSingle(List<String> imagePaths) {
ImageWriter imageWriter = ImageIO.getImageWritersByFormatName("tiff").next();
ByteArrayOutputStream byteArrayOutputStream = null;
try {
byteArrayOutputStream = new ByteArrayOutputStream();
ImageOutputStream outputStream = ImageIO.createImageOutputStream(byteArrayOutputStream);
imageWriter.setOutput(outputStream);
imageWriter.prepareWriteSequence(null);
for (String path : imagePaths) {
BufferedImage image = ImageIO.read(new FileInputStream(path));
ImageWriteParam writeParams = imageWriter.getDefaultWriteParam();
IIOMetadata metadata = imageWriter.getDefaultImageMetadata(new ImageTypeSpecifier(image),
writeParams);
IIOImage iioImage = new IIOImage(image, null, metadata);
imageWriter.writeToSequence(iioImage, null);
}
imageWriter.endWriteSequence();
byteArrayOutputStream.close();
} catch (IOException e) {
System.out.println(e.getLocalizedMessage());
}
return byteArrayOutputStream;
}我调试代码,BufferedImage和IIOImage变量不是null。但是endWriteSequence方法不将图像的内容写入ImageOutputStream。因此,ImageOutputStream和ByteArrayOutputStream变量是空的。我浏览了相关的问题和正式文件,但没有找到任何有用的信息。
发布于 2022-05-24 13:26:34
正如我在最初的评论中所写的,代码有一个小问题,就是您没有正确地刷新/关闭outputStream (包装byteArrayOutputStream的ImageOutputStream )。相反,您只关闭ByteArrayOutputStream (这是一个非操作)。这意味着如果流实现执行内部缓存/缓冲,它将永远不会被刷新到底层流。在我非常有限的测试中,我可以重现问题,而这似乎确实是事实。
一个更安全、更惯用的Java 7+版本的代码将使用试用资源创建包装的蒸汽,并修复这个问题(通过自动调用close()):
public static ByteArrayOutputStream mergeIntoSingle(List<String> imagePaths) {
ImageWriter imageWriter = ImageIO.getImageWritersByFormatName("tiff").next();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try (ImageOutputStream outputStream = ImageIO.createImageOutputStream(byteArrayOutputStream)) {
imageWriter.setOutput(outputStream);
imageWriter.prepareWriteSequence(null);
for (String path : imagePaths) {
BufferedImage image = ImageIO.read(new FileInputStream(path));
ImageWriteParam writeParams = imageWriter.getDefaultWriteParam();
IIOMetadata metadata = imageWriter.getDefaultImageMetadata(new ImageTypeSpecifier(image),
writeParams);
IIOImage iioImage = new IIOImage(image, null, metadata);
imageWriter.writeToSequence(iioImage, null);
}
imageWriter.endWriteSequence();
} catch (IOException e) {
System.out.println(e.getLocalizedMessage());
}
return byteArrayOutputStream;
}PS:我认为TIFFImageWriter应该在endWriteSequence()方法中的流中调用flush() ( TwelveMonkeys库就是这样做的)。但是,您应该始终确保关闭所打开的任何流,因此上述代码在任何情况下都更好。
https://stackoverflow.com/questions/72362975
复制相似问题