Ограничения размера QImage/QPixmap?

есть ли известный размер/пространство ограничение QPixmap и/или QImage документированные объекты? Я не нашел никакой полезной информации по этому поводу. В настоящее время я использую Qt 4.7.3 на OSX и Windows. Особенно меня интересует:

  • ограничения по ширине/высоте?
  • ограничения в зависимости от цветового формата?
  • разница между 32/64 битные машины?
  • разница в отношении ОС?

Я наивно подозреваю, что память-это только ограничение, поэтому можно рассчитать максимальный размер по

ширина x Высота x byte_per_pixel

Я предполагаю, что существует более сложное эмпирическое правило; также 32-битные машины могут иметь проблемы при работе с измерениями GB.

В конце концов, я хочу сохранить несколько изображений RGBA размером около 16000x16000 пикселей и отобразить их с помощью прозрачности друг на друга в QGraphicsScene. Доступная рабочая станция может иметь много ОЗУ, скажем 16ГБ.

tl; dr: какие ограничения размера QImage/QPixmap вы знаете, или где я могу найти такую информацию?

Edit: я знаю о подходе плитки, и я в порядке с этим. И все же было бы здорово узнать то, что описано выше.

спасибо!

4 ответов


оба ограничены 32767x32767 пикселей. То есть вы можете думать о них как об использовании подписанного 16-битного значения для разрешения X и Y.

никакая ось не может превысить 32767 пикселов, даже если другая ось только 1 пиксел. Операционная система "bitness"не влияет на ограничение. Основная система может столкнуться с другими ограничениями, такими как память, как вы упомянули, прежде чем такой огромный образ может быть создан.

вы можете увидеть пример такого ограничения в следующем исходный код: 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;
}

основываясь на ответе @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-битных ints).


у меня действительно был случай взглянуть на это в одно время. Выполните поиск в исходном коде qimage.cpp для "проверки здравомыслия для потенциальных переполнений", и вы можете увидеть проверки, которые делает Qt. В основном,

  • количество требуемых байтов (ширина * высота * depth_for_format) должно быть меньше INT_MAX.
  • он должен быть в состоянии malloc эти байты в момент создания QImage экземпляра.

вы создаете 64-битное приложение? Если нет, вы очень быстро столкнетесь с проблемами памяти. В Windows, даже если машина имеет 16GB ram, 32-битный процесс будет ограничен 2GB (если это не LARGEADDRESSAWARE, то 3GB). Изображение 16000x16000 будет чуть меньше 1 ГБ, поэтому вы сможете выделить достаточно памяти только для 1, возможно, 2, Если вам очень повезет.

с 64-битным приложением вы сможете выделить достаточно памяти для нескольких изображений.