Ограничения размера QImage / QPixmap? - PullRequest
10 голосов
/ 16 августа 2011

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

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

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

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

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

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

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

Редактировать: Я знаю о подходе мозаичного размещения, и я в порядке с этим. Тем не менее, было бы здорово узнать вещи, описанные выше.

Спасибо!

Ответы [ 4 ]

11 голосов
/ 16 августа 2011

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

Ни одна ось не может превышать 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;
}
5 голосов
/ 14 июля 2014

Основываясь на ответе @ 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 голосов
/ 16 августа 2011

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

  • Требуемое количество байтов (ширина * высота * глубина_формата) должно быть меньше INT_MAX.
  • Он должен иметь возможность malloc этих байтов в момент создания экземпляра QImage.
0 голосов
/ 18 августа 2011

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

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

...