13

是否有任何已知的大小/空间限制QPixmap和/或QImage记录的对象?我没有找到任何有用的信息。我目前在 OSX 和 Windows 上使用 Qt 4.7.3。我特别感兴趣:

  • 宽度/高度限制?
  • 限制取决于颜色格式?
  • 32/64位机器的区别?
  • 关于操作系统的区别?

我会天真地怀疑内存是唯一的限制,因此可以通过以下方式计算最大大小

宽度 x 高度 x byte_per_pixel

我假设有一个更详尽的经验法则;当您遇到 GB 尺寸时,32 位机器也可能存在寻址问题。

最后,我想存储多个大小约为 16000x16000 像素的 RGBA 图像,并在QGraphicsScene. 可用的工作站可以有很多 RAM,比如说 16GB。

tl;dr:你知道 QImage/QPixmap 的大小限制是多少,或者我在哪里可以找到这些信息?

编辑:我知道平铺方法,我对此很好。仍然很高兴知道上面描述的事情。

谢谢!

4

4 回答 4

13

两者都限制为 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;
}
于 2011-08-16T15:37:45.140 回答
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 位整数)。

于 2014-07-14T01:51:48.010 回答
2

实际上,我有一次有机会对此进行研究。在源代码中qimage.cpp搜索“针对潜在溢出的健全性检查”,您可以看到 Qt 正在执行的检查。基本上,

  • 所需的字节数(宽度 * 高度 * depth_for_format)必须小于INT_MAX.
  • 它必须能够malloc在您创建QImage实例时获取这些字节。
于 2011-08-16T15:49:45.833 回答
1

您正在构建 64 位应用程序吗?如果没有,您将很快遇到内存问题。在 Windows 上,即使机器有 16GB 内存,32 位进程也将被限制为 2GB(除非它是 LARGEADDRESSAWARE 然后 3GB)。一个 16000x16000 的图像将略低于 1 GB,因此您只能为 1 个分配足够的内存,如果您非常幸运,也许可以为 2 个分配内存。

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

于 2011-08-18T14:10:17.707 回答