Java 将TIFF图像逐块写入outputstream
我试图动态创建一个巨大的TIFF图像,而不将整个图像保存在内存中。我之所以选择TIFF格式,是因为它似乎是Java ImageWriter中唯一支持此功能的格式 然而,无论我尝试什么,我都会得到一个多页文件(当我使用Java 将TIFF图像逐块写入outputstream,java,javax.imageio,Java,Javax.imageio,我试图动态创建一个巨大的TIFF图像,而不将整个图像保存在内存中。我之所以选择TIFF格式,是因为它似乎是Java ImageWriter中唯一支持此功能的格式 然而,无论我尝试什么,我都会得到一个多页文件(当我使用writeToSequence方法时)或一个只包含最后一个磁贴的图像(当我使用write()方法时) 我的基本代码如下所示: final ImageWriter tiffImageWriter = ImageIO.getImageWritersByFormatName
writeToSequence
方法时)或一个只包含最后一个磁贴的图像(当我使用write()
方法时)
我的基本代码如下所示:
final ImageWriter tiffImageWriter = ImageIO.getImageWritersByFormatName("TIFF").next();
final ImageWriteParam param = tiffImageWriter.getDefaultWriteParam();
param.setTilingMode(MODE_EXPLICIT);
param.setTiling(TILE_SIZE, TILE_SIZE, 0, 0);
try (ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(response.getOutputStream())) {
tiffImageWriter.setOutput(imageOutputStream);
for (int tileX = 0; tileX < 10; tileX++) {
for (int tileY = 0; tileY < 10; tileY++) {
final BufferedImage bufferedImage = ... // some method producing a BufferedImage of size TILE_SIZExTILE_SIZE
tiffImageWriter.write(null, new IIOImage(bufferedImage, null, null), param);
imageOutputStream.flush();
}
}
}
tiffImageWriter.dispose();
final ImageWriter tiffImageWriter=ImageIO.getImageWritersByFormatName(“TIFF”).next();
最终ImageWriteParam参数=tiffImageWriter.getDefaultWriteParam();
参数setTilingMode(模式_显式);
参数设置平铺(平铺尺寸,平铺尺寸,0,0);
try(ImageOutputStream ImageOutputStream=ImageIO.createImageOutputStream(response.getOutputStream())){
tiffImageWriter.setOutput(imageOutputStream);
对于(int-tileX=0;tileX<10;tileX++){
对于(int-tileY=0;tileY<10;tileY++){
final BuffereImage BuffereImage=…//生成大小为TILE\u SizeTextile\u size的BuffereImage的某些方法
tiffImageWriter.write(null,新IIOImage(BuffereImage,null,null),参数);
imageOutputStream.flush();
}
}
}
tiffImageWriter.dispose();
这里的response.getOutputStream()
是来自我的服务的输出流
运行此代码的结果是TILE\u SIZE x TILE\u SIZE
SIZE的图像,最后一个TILE作为内容
我想知道是否有可能做到这一点,或者这项功能是为其他目的而设计的?正如您已经了解到的,
write
和writeToSequence
在这种情况下不起作用。他们不应该这样做。这些方法分别用于写入单个图像文件或多个图像文件。它们不用于部分写入图像。要使用javax.imageio
API编写图像,而不必一次将整个图像保存在内存中,您至少有两个选项:
- 使用一个平铺的
。您需要创建一个自定义实现,按需创建每个磁贴(您可能已经这样做了)。但正如您在中所了解的,磁贴大小(以及写入程序是否会使用磁贴)取决于渲染图像
实现。因此,您可能需要调整所用书写器的磁贴大小。并且可能有一个内存中的磁贴缓存来获得良好的性能ImageWriter
- 使用
方法ImageWriter
/canWriteEmpty
,如果它们都返回canReplacePixels
,则使用true
/prepareWriteEmpty
(对于整个图像),然后为每个磁贴使用endWriteEmpty
,prepareReplacePixels
。这似乎适用于JAI或Java9+replacePixels
(仅适用于未压缩图像)。我知道目前这并不适用于TwelveMonkeysTIFFImageWriter
,因为这是一个非常罕见的用例TIFFImageWriter
考虑到您的代码示例和期望,第二个选项似乎与您想要的最接近。这里的QA似乎与您的问题重复:如果它对您有效,您可以让我们知道,我们可以让这个问题重复吗?@ControlAltDel一点也不,与我的问题无关。那么,你能把它作为一个完整的例子吗?甚至可能只是生成一个带有一些简单图形的BuffereImage,以及您希望它们如何结合在一起。