【问题标题】:QImage/QPixmap size limitations?QImage/QPixmap 大小限制?
【发布时间】:2011-10-28 03:31: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 的大小限制是多少,或者我在哪里可以找到这些信息?

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

谢谢!

【问题讨论】:

    标签: qt qt4 qimage qpixmap


    【解决方案1】:

    两者都限制为 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 的答案。
    • 有人能详细说明什么是“轴”吗?我在缩放由此引起的图像时遇到了渲染问题,但我的撕裂开始时间与 32767 不一致。我可以在无法正确渲染 qpixmap 之前将 1000000x200 图像缩放 41000x。
    • 另外,我看到 sn-p 来自 QPixmap::fromImage 函数;如果像素图是使用带有文件名的构造函数创建的,那么限制在哪里?
    【解决方案2】:

    基于@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) &lt; uint(height)
    • INT_MAX &lt; uint(height) * uint(bpl)
    • INT_MAX &lt; height * width * depth_in_bytes

    因此,您的图像总大小必须小于 2147483647(对于 32 位整数)。

    【讨论】:

      【解决方案3】:

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

      • 所需的字节数(width * height * depth_for_format)必须小于INT_MAX
      • 在您创建QImage 实例时,它必须能够malloc 那些字节。

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-05-14
          • 2012-04-13
          • 1970-01-01
          • 2013-04-18
          • 2012-05-05
          • 2012-01-11
          相关资源
          最近更新 更多