QImage/QPixmap的大小限制是什么?

14
有没有关于QPixmap和/或QImage对象大小/空间限制的已知文档?我没有找到任何有用的信息。我目前正在使用Qt 4.7.3在OSX和Windows上。特别是我感兴趣的是:
  • 宽度/高度限制?
  • 取决于颜色格式的限制?
  • 32/64位机器之间的差异?
  • 关于操作系统的差异?
我天真地认为内存是唯一的限制,因此可以通过以下方式计算最大尺寸:

宽度x高度x每像素字节数

我假设有一个更详细的经验法则;还有32位机器可能会在运行GB维度时出现寻址问题。
最后,我想存储约16000x16000像素大小的多个RGBA图像,并在QGraphicsScene中使用透明度将它们渲染到彼此上面。可用的工作站可以拥有大量RAM,比如16GB。 tl;dr:您了解的QImage/QPixmap的尺寸限制是什么,或者我在哪里可以找到这样的信息? 编辑:我知道平铺方法并且对此感到满意。仍然很好了解上述内容。
谢谢!
5个回答

14

这两者都被限制在32767x32767像素之内。也就是说,可以将它们视为在X和Y分辨率上使用带符号的16位值。

任何一个轴都不能超过32767个像素,即使另一个轴只有1个像素。操作系统的“位数”不会影响该限制。在创建如此巨大的图像之前,底层系统可能会遇到其他限制,例如您提到的内存。

您可以在以下源代码中看到此限制的示例: http://git.zx2c4.com/qt/plain/src/gui/image/qpixmap_x11.cpp

if (uint(w) >= 32768 || uint(h) >= 32768) {
    w = h = 0;
    is_null = true;
    return;
}

这可能对于 QPixmap 是正确的,但是对于 QImage 的限制,请参考 @povman 的回答。 - Thorbjørn Lindeijer
有人能详细解释一下什么是“轴”吗?我在缩放图像时遇到了渲染问题,这是由于轴引起的,但我的结果与32767不一致。我可以将1000000x200的图像缩放到41000x,然后才无法正确渲染qpixmap。 - quimnuss
此外,我看到这个代码片段来自于 QPixmap::fromImage 函数;如果使用带有文件名的构造函数创建 pixmap,限制在哪里设置? - quimnuss

8

在@charles-burns的回答基础上,以下是与QImage相关的源代码:

QImageData *d = 0;

if (format == QImage::Format_Invalid)
    return d;

const int depth = qt_depthForFormat(format);
const int calc_bytes_per_line = ((width * depth + 31)/32) * 4;
const int min_bytes_per_line = (width * depth + 7)/8;

if (bpl <= 0)
    bpl = calc_bytes_per_line;

if (width <= 0 || height <= 0 || !data
    || INT_MAX/sizeof(uchar *) < uint(height)
    || INT_MAX/uint(depth) < uint(width)
    || bpl <= 0
    || height <= 0
    || bpl < min_bytes_per_line
    || INT_MAX/uint(bpl) < uint(height))
    return d;                                        // invalid parameter(s)

这里的bpl是每行的字节数,实际上等于width * depth_in_bytes。对最后一个无效测试进行代数运算:
  • INT_MAX/uint(bpl) < uint(height)
  • INT_MAX < uint(height) * uint(bpl)
  • INT_MAX < height * width * depth_in_bytes
因此,您的图像总大小必须小于2147483647(32位整数)。

2

我曾经有机会研究过这个问题。在qimage.cpp的源代码中搜索“sanity check for potential overflows”,你就可以看到Qt正在进行的检查。基本上,

  • 所需字节数(宽度*高度*深度)必须小于INT_MAX
  • 在创建QImage实例时,必须能够使用malloc分配这些字节。

1

你正在开发一个64位应用程序吗?如果不是,你很快就会遇到内存问题。在Windows上,即使机器有16GB的内存,32位进程也将被限制为2GB(除非它是LARGEADDRESSAWARE,然后为3GB)。一个16000x16000像素的图像将只占用不到1GB的空间,因此你只能为1个图像分配足够的内存,如果你非常幸运,可能可以为2个图像分配足够的内存。

使用64位应用程序,你应该能够为多个图像分配足够的内存。


0

当我尝试将大小为6160x4120的JPEG加载到QPixmap时,我收到了这个警告:"qt.gui.imageio: QImageIOHandler: Rejecting image as it exceeds the current allocation limit of 128 megabytes"并返回空的QPixmap

这似乎是我迄今为止发现的最严格的限制。

然而,有一种方法可以通过void QImageReader::setAllocationLimit(int mbLimit)来增加此限制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接