Sono abbastanza nuovo in C++/Qt e sto provando a creare un'applicazione con Visual Studio C++ e Qt (4.8.3). L'applicazione visualizza le immagini utilizzando un QGraphicsView, ho bisogno di cambiare le immagini a livello di pixel.Problemi con QImage di grandi dimensioni
Il codice di base è (semplificato):
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);
Questo funziona bene per le immagini fino a circa 12000x6000 pixel. La cosa strana accade oltre questa dimensione. Quando imposto img_width=16000
e img_height=8000
, ad esempio, la riga img = new QImage(...)
restituisce un'immagine nulla. I dati dell'immagine dovrebbero essere intorno a 512.000.000 byte, quindi non dovrebbe essere troppo grande, anche su un sistema a 32 bit. Inoltre, la mia macchina (Win 7 64 bit, 8 GB RAM) dovrebbe essere in grado di contenere i dati.
Ho anche provato questa versione:
uchar* imgbuf = (uchar*) malloc(img_width*img_height*4);
QImage* img = new QImage(imgbuf,img_width,img_height,QImage::Format_RGB32);
In un primo momento, questo funziona. Il puntatore img è valido e chiamando img->width()
per esempio restituisce la larghezza dell'immagine corretta (invece di 0, nel caso in cui il puntatore dell'immagine sia nullo). Ma non appena chiamo img->setPixel()
, il puntatore diventa nullo e img->width()
restituisce 0.
Quindi cosa sto facendo di sbagliato? O c'è un modo migliore di modificare le immagini di grandi dimensioni a livello di pixel?
saluti, David
Provare a azzerare manualmente la memoria del malloc'd per verificare se l'allocazione funziona effettivamente. –
Dai un'occhiata a questo: [Qt Project Wiki: caricamento di immagini grandi] (http://qt-project.org/wiki/LoadingLargeImages) – dschulz
Ricorda che su un'applicazione Windows a 32 bit l'allocazione più grande di default è possibile ottenere come risultato di la frammentazione dello spazio degli indirizzi sarà di circa 1,2 GB (dello spazio di indirizzamento dell'applicazione da 2 GB) senza utilizzare il flag del linker/LARGEADDRESSAWARE e/o la ridefinizione delle DLL che l'applicazione utilizza per ridurre la frammentazione. – drescherjm