【问题标题】:BufferedImage in java larger than 2^31 pixelsjava中的BufferedImage大于2 ^ 31像素
【发布时间】:2017-07-04 21:26:41
【问题描述】:

我需要在 java 中创建一个非常大的图像,到目前为止我一直在使用 java.awt.image.BufferedImage 类。但似乎这个类用 int 存储它的像素,因为它不能超过 2^31 像素。我曾考虑过创建较小的图像并将它们拼接在一起,但问题是我尝试使用的照片编辑器(如 Adob​​e Photoshop)甚至无法导入任何尺寸大于 30,000 像素的照片。

我曾考虑过制作自己的图像类,但我的知识还不够丰富,无法将所有内容都纳入其中。

有什么建议吗? 谢谢你

【问题讨论】:

  • 为什么它需要是一个图像?或者您可以使用某种堆外 2D 缓冲区吗?您自己说,即使您以某种方式做到了这一点,它也无法在任何程序中使用。根据现有信息,这似乎是一个非常奇怪的问题。如此广泛,它可能会被标记为离题。如果您提供更多详细信息,也许有人可以帮助您了解自定义图像的想法,如果这确实是您需要的(可能使用自定义 java.awt.image.{DataBuffer,Raster,...})。
  • 我正在创建生成类似分形图片的迭代函数系统图像,并且我正计划制作这些图像的大型打印件。
  • 请注意,即使您可以绕过 Java BufferedImage 类中的限制,图像文件格式仍然存在限制。例如JPEG 在每个维度上最多支持 65535 像素,而 TIFF 的最大文件大小为 4Gb。您打算为打印机提供什么格式?
  • 取决于你的绘图功能是如何工作的,如果从上到下一次画一条线,你可以简单地画出每一条线并将其直接写入磁盘。这可能是原始 RBG 格式,然后您可以将其与其他内容一起处理为另一种图像格式。
  • 必须是BufferedImage吗? BufferedImage 类通常由单个数组支持,这使得 Java 数组大小限制成为更多问题,而不是物理内存。不过,您可以尝试自定义 DataBuffer 实现。如果您能够一次处理图像的区域,我还将研究支持图块的RenderedImage 接口。

标签: java image bufferedimage


【解决方案1】:

您可能很难加载该大小内存的图像,因为 2^31 x 1px 的图像的内存占用将是:

2^31px * 1px * 4 bytes/px = 4,294,967,296 bytes = ~4.2 GB

一个 2^31px x 4px 的图像已经消耗了比大多数计算机更多的内存。将图像拼接在一起是这种情况的正确设计。一个简单的解决方案是保留一个多维图像数组,并根据您的要求将它们加载到内存中。

ImageMagick 是一个成熟的图像处理工具,它可以支持非常大的图像尺寸。既然你说你想写一个大的图像文件,我建议使用montage feature。渲染部分分形并将它们保存到磁盘,然后在渲染完成后,从您的程序中调用 ImageMagick montage 命令以生成最终的大文件。

【讨论】:

  • 我正在运行一个 32GB 的工作站,所以这还不是我的问题。您将如何将图像写入单个图像文件?
  • 就我个人而言,我会使用 ImageMagick,因为自己编写它可能会很困难。尤其是当您必须处理图像文件格式并尝试逐步构建大图像文件时。看看 ImageMagick 的蒙太奇功能。 imagemagick.org/Usage/montage您将分形的每个部分写入磁盘,然后在最后使用 ImageMagick 生成完整的文件。
【解决方案2】:

我发现 GIMP 能够导入任何尺寸为 2^31 或更小的照片,所以我可以用它来拼接照片。感谢所有回复的人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-10
    • 2013-02-17
    • 2023-03-21
    • 2011-08-06
    • 1970-01-01
    • 1970-01-01
    • 2023-02-04
    • 1970-01-01
    相关资源
    最近更新 更多