如何组合图像而不将它们加载到Java中的RAM中

时间:2011-10-05 22:44:30

标签: java image memory bufferedimage

我正在尝试生成一个非常大的(大约一千万像素)图像,到目前为止,我只能在BufferedImage中创建高达约40万像素的图像,然后才会出现内存不足错误。我想逐片构建图像,然后将组合而不用将图像加载到内存中。我也可以通过将每个部分写入文件来完成此操作,但ImageIO不支持此功能。

4 个答案:

答案 0 :(得分:1)

我认为JAI可以帮助您构建自己想要的东西。我建议查看JAI提供的数据结构和流。

另外,看看这些问题,可能会帮助你提出想法。

  1. How to save a large fractal image with the least possible memory footprint
  2. How to create a big image file from many tiles
  3. Appending to an Image File
  4. 你基本上想要在那里扭转2 祝你的项目好运;)

答案 1 :(得分:0)

不是一个合适的解决方案,只是一个草图。

压缩图像时,打开一张图像并不容易。您可以通过外部工具将图像解压缩为一些简单的格式(xpm,未压缩的tiff)。然后你可以将这个图像的部分加载为字节数组,因为格式非常简单,并且可以从这些原始数据中创建Image实例。

答案 2 :(得分:0)

我看到两个简单的解决方案。为您的图像创建自定义二进制格式。要保存,只需一次生成一个零件,搜索()到文件中的适当位置,然后卸载数据。要加载,请搜索()到文件中的适当位置,然后加载数据。

另一种解决方案是自己学习图像格式。 bmp是未压缩的,但是唯一容易学习的东西。一旦学会了,上述步骤就能很好地发挥作用。

请记住将图像转换为字节数组以便于存储。

答案 3 :(得分:0)

如果没有办法将其内置到Java中(为了您的利益,我希望情况并非如此,有人回答这么说),那么您需要自己实现一个算法,就像其他人在这里评论说的那样如此。

您不一定需要自己了解整个算法。如果你采用预先存在的算法,你可以修改它以将文件作为字节流加载,创建一个字节缓冲区以保持读取文件的块,并修改算法以一次接受这个数据块。 / p>

某些算法(例如jpg)可能无法以这种方式使用线性文件块流来实现。正如@warren所建议的那样,bmp可能是最容易实现的,因为该文件格式只有一个包含这么多字节的标题,然后它只是以二进制格式直接转储RGBA数据(以及一些填充)。因此,如果您要加载需要组合的子图像,请一次一个地加载它们(尽管您实际上可以多线程处理这个东西并同时加载下一个数据以加速它,因为此过程将采取很长一段时间),读取下一行数据,将其保存到二进制输出流,依此类推。

您甚至可能需要多次加载子图像。例如,想象保存的图像由2x2网格中的4个子图像组成。您可能需要加载图像1,读取其第一行数据,将其保存到新文件,释放图像1,加载图像2,读取其第一行数据,保存,释放2,加载1以读取其第二行数据,等等。如果使用压缩图像格式进行保存,则更有可能需要执行此操作。

再次建议一个bmp,因为bmp没有被压缩,你只需要以你想要的任何格式保存数据(假设文件是​​以提供随机访问的方式打开的),你可以在文件中跳过你&# 39;重新保存,以便您可以完全读取1个子图像并保存所有数据,然后再转到下一个。这可能会节省运行时间,但也可能会提供可怕的文件大小。

我可以继续。可能存在多个陷阱,优化等等。

如果你创建了一个新的图像文件格式,它只是由元数据组成,允许它以一种逻辑上合并它们的方式引用其他文件,而不是保存一个由于组合其他文件而导致的大文件实际创建一个大型文件?是否创建新的图像文件格式取决于您的软件;如果您希望人们将这些图像用于其他软件,那么这将无法工作 - 至少,除非您能够使您的新图像文件格式流行并成为标准。