Проблемы с большим QImage

Я довольно новичок в C ++ / Qt и пытаюсь создать приложение с Visual Studio C ++ и Qt (4.8.3). Приложение отображает изображения с помощью QGraphicsView, мне нужно изменить изображения на уровне пикселей.

Основной код (упрощенный):

QImage* img = new QImage(img_width,img_height,QImage::Format_RGB32);
while(do_some_stuff) {
img->setPixel(x,y,color);
}
QGraphicsPixmapItem* pm = new QGraphicsPixmapItem(QPixmap::fromImage(*img));
QGraphicsScene* sc = new QGraphicsScene;
sc->setSceneRect(0,0,img->width(),img->height());
sc->addItem(pm);
ui.graphicsView->setScene(sc);

Это хорошо работает для изображений размером до 12000×6000 пикселей. Странная вещь происходит за пределами этого размера. Когда я установил img_width=16000 а также img_height=8000например, строка img = new QImage(...) возвращает нулевое изображение. Данные изображения должны составлять около 512 000 000 байт, поэтому они не должны быть слишком большими даже в 32-разрядной системе. Кроме того, моя машина (Win 7 64-битная, 8 ГБ ОЗУ) должна быть способна хранить данные.

Я также попробовал эту версию:

uchar* imgbuf = (uchar*) malloc(img_width*img_height*4);
QImage* img = new QImage(imgbuf,img_width,img_height,QImage::Format_RGB32);

Сначала это работает. Указатель img действителен и вызывает img->width() например, возвращает правильную ширину изображения (вместо 0, если указатель изображения нулевой).
Но как только я позвоню img->setPixel()указатель становится нулевым и img->width() возвращает 0

Так что я делаю не так? Или есть лучший способ изменения больших изображений на уровне пикселей?

С Уважением,
Дэвид

5

Решение

Ваш второй подход — верный путь. Проблема, с которой вы сталкиваетесь, это когда вы звоните setPixel(), QImage создает копию предоставленного вами внешнего буфера и не хватает памяти для него.

Попробуйте изменить значение пикселя непосредственно в предоставленном буфере. Ты можешь использовать scanLine() получить указатель на буфер строки. Я бы не использовал setPixel() во всяком случае, так как это очень медленно.

1

Другие решения

QImage поддерживает изображения максимум 32768×32768 пикселей (сокращенная подпись). Это следует из условия: ширина * высота * colordepth < INT_MAX (4 миллиарда) -> 32768 * 32768 * 4 = 4 миллиарда. Второе условие, конечно, состоит в том, что malloc может выделить запрошенную память.

Если вам действительно нужны большие изображения, вам придется использовать другую обертку или разделить на несколько QImage.

4

Я разыскал проблему. Я просто забыл добавить /LARGEADDRESSAWARE пометьте параметры компоновщика.

Я также очень ценю ответ Стивена Чу с подсказкой scanLine (). Во-первых, это экономит память, во-вторых, это действительно намного быстрее.

Теперь я могу безопасно создавать изображения размером до 32000×16000 пикселей, что было моей желаемой целью.

2
По вопросам рекламы [email protected]