使用 Java 中的 ImageIO 编写 TIFF 的平铺输出

发布于 2024-11-27 12:29:31 字数 1376 浏览 2 评论 0原文

我拥有的是大量的帧,需要将它们放在一起形成更大的图像(如马赛克)。所需的图像位置是已知的。

图像数量非常多,因此将它们全部加载到内存中是不切实际的。

基于这里的一些其他答案,我能够重写 RenderedImage 中的方法(特别是 getData(rect))以加载适当的数据并返回它。

这工作得很好,但是图像编写器总是调用 getData 并请求数据行。在我看来,我应该能够更改 ImageWriterParam 以调用单个图块,但是当我尝试写入函数时,它仍然调用 getData 中的一行。

我怎样才能强制它使用tile并调用getTile来代替。

BufferedOutputStream bos=null;
try {
   bos = new BufferedOutputStream(new FileOutputStream(new File("test2.tiff")));

   ImageWriter writer =(ImageWriter) ImageIO.getImageWritersBySuffix("tif").next();

   ImageOutputStream ios=null

   ios = ImageIO.createImageOutputStream(bos); 

   writer.setOutput(ios);
   ImageWriteParam param = writer.getDefaultWriteParam();
   param.setTilingMode(ImageWriteParam.MODE_DEFAULT);

   RenderedImage mosaic = new MosaicImage(imageFiles[]);

   writer.write(null,new IIOImage(mosaic,null,null),param);

    } catch (FileNotFoundException ex) {

    }

注意我可以使用 param.setTilingMode(ImageWriteParam.MODE_EXPLICIT); 和 setTiling(w,h,xoff,yoff);

但是使用它时,writer.write 仍然在我的图像中调用 getData(rect),并且非常烦人的是不调用由 w,h 指定大小的矩形。它调用一个大小不同的矩形(可能来自某些东西)

例如,如果我使用 setTiling(100,100,0,0);

人们会期望,即使它没有从图像调用 getTile,传递给 getData 的 Rectangle 应该是 (0,0,100,100),但它传递的是 Rectangle (0,0,96,96),它不是图像宽度的倍数或我能想到的还有什么。

感谢您的帮助

What I have is a a large number of frames that need to be placed together in a larger image (like a mosaic). The required positions of the images are known.

There are a very large number of images so loading them all into memory is impractical at best.

Based on some other answers here I was able to override the methods in RenderedImage (specifically getData(rect)) to load in the appropriate data and return it.

This works just fine, however the image writer is always calling getData and requesting rows of data. It seems to me I should be able to change the ImageWriterParam to call for individual tiles instead, but when I tried the write function still calls for a single line from getData.

How can I force this to use tiles and call getTile instead.

BufferedOutputStream bos=null;
try {
   bos = new BufferedOutputStream(new FileOutputStream(new File("test2.tiff")));

   ImageWriter writer =(ImageWriter) ImageIO.getImageWritersBySuffix("tif").next();

   ImageOutputStream ios=null

   ios = ImageIO.createImageOutputStream(bos); 

   writer.setOutput(ios);
   ImageWriteParam param = writer.getDefaultWriteParam();
   param.setTilingMode(ImageWriteParam.MODE_DEFAULT);

   RenderedImage mosaic = new MosaicImage(imageFiles[]);

   writer.write(null,new IIOImage(mosaic,null,null),param);

    } catch (FileNotFoundException ex) {

    }

Note I can use param.setTilingMode(ImageWriteParam.MODE_EXPLICIT); and setTiling(w,h,xoff,yoff);

However when using this, writer.write still calls getData(rect) in my image, and very annoyingly does not call for a rectangle of the size specified by w,h. It calls a rectangle of a size that is different by some random amount(probably comes from something)

For example if I use setTiling(100,100,0,0);

one would expect that even if it does not call getTile from the image, the Rectangle passed to getData should be (0,0,100,100) but instead it passes Rectangle (0,0,96,96) which is not a multiple of the image width or anything else i can think of.

Thanks for any help

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

脱离于你 2024-12-04 12:29:31

如果您阅读 TileWidth 和 TileLength 字段下的 TIFF 6.0 规范,您会发现文本

TileWidth 必须是 16 的倍数。此限制得到改善
某些图形环境中的性能并增强兼容性
使用 JPEG 等压缩方案。

TileLength 也类似。 100x100 不能被 16 整除,但 96x96 可以,我敢打赌 TIFF 编码器会尽力满足您的要求。

If you read up on the TIFF 6.0 spec under the TileWidth and TileLength fields, you will find the text

TileWidth must be a multiple of 16. This restriction improves
performance in some graphics environments and enhances compatibility
with compression schemes such as JPEG.

And similar for TileLength. 100x100 isn't divisible by 16, but 96x96 is, which I bet is the TIFF encoder trying its best to fullfill your request.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文