Tôi khá mới đối với C++/Qt và tôi đang cố gắng tạo một ứng dụng với Visual Studio C++ và Qt (4.8.3). Ứng dụng hiển thị hình ảnh bằng cách sử dụng QGraphicsView, tôi cần thay đổi hình ảnh ở mức pixel.Các vấn đề với QImage lớn
Mã cơ bản (giản thể):
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);
này hoạt động tốt cho hình ảnh lên đến khoảng 12000x6000 pixel. Điều kỳ lạ xảy ra ngoài kích thước này. Khi tôi đặt img_width=16000
và img_height=8000
, ví dụ: dòng img = new QImage(...)
trả về một hình ảnh rỗng. Dữ liệu hình ảnh nên có khoảng 512.000.000 byte, do đó, nó không nên quá lớn, ngay cả trên một hệ thống 32 bit. Ngoài ra, máy của tôi (Win 7 64bit, 8 GB RAM) nên có khả năng giữ dữ liệu.
Tôi cũng đã thử phiên bản này:
uchar* imgbuf = (uchar*) malloc(img_width*img_height*4);
QImage* img = new QImage(imgbuf,img_width,img_height,QImage::Format_RGB32);
Lúc đầu, công trình này. Con trỏ img là hợp lệ và gọi số img->width()
ví dụ trả về chiều rộng hình ảnh chính xác (thay vì 0, trong trường hợp con trỏ hình là rỗng). Nhưng ngay sau khi tôi gọi img->setPixel()
, con trỏ trở thành null và img->width()
trả về 0.
Vì vậy, tôi đang làm gì sai? Hoặc là có cách nào tốt hơn để sửa đổi hình ảnh lớn trên cấp pixel?
Kính trọng, David
Cố gắng không bằng tay bộ nhớ malloc'd trước để xem liệu phân bổ có thực sự hoạt động hay không. –
Hãy xem xét điều này: [Qt Project Wiki: Loading Large Images] (http://qt-project.org/wiki/LoadingLargeImages) – dschulz
Hãy nhớ rằng trên một ứng dụng 32 bit cửa sổ phân bổ lớn nhất mặc định bạn có thể tạo ra kết quả phân vùng không gian địa chỉ sẽ là khoảng 1,2 GB (không gian địa chỉ ứng dụng 2GB) mà không sử dụng cờ liên kết/LARGEADDRESSAWARE và/hoặc rebasing các dll mà ứng dụng của bạn sử dụng để giảm phân mảnh. – drescherjm