Ограничения размера 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-битным приложением вы сможете выделить достаточно памяти для нескольких изображений.