2012-11-26 14 views
5

के साथ समस्याएं मैं सी ++/क्यूटी के लिए काफी नया हूं और मैं विजुअल स्टूडियो सी ++ और क्यूटी (4.8.3) के साथ एक एप्लिकेशन बनाने की कोशिश कर रहा हूं। एप्लिकेशन QGraphicsView का उपयोग कर छवियों को प्रदर्शित करता है, मुझे छवियों को पिक्सेल स्तर पर बदलने की आवश्यकता है।बड़े QImage

बुनियादी कोड (सरलीकृत) है:

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); 

यह चारों ओर 12000x6000 पिक्सेल अप करने के लिए छवियों के लिए अच्छी तरह से काम करता है। अजीब चीज इस आकार से परे होती है। जब मैं img_width=16000 और img_height=8000 सेट करता हूं, उदाहरण के लिए, रेखा img = new QImage(...) एक शून्य छवि देता है। छवि डेटा लगभग 512,000,000 बाइट होना चाहिए, इसलिए यह 32 बिट सिस्टम पर भी बहुत बड़ा नहीं होना चाहिए। इसके अलावा, मेरी मशीन (विन 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->width() पर कॉल करना उदाहरण के लिए सही छवि चौड़ाई (0 के बजाय, छवि सूचक शून्य होने पर) देता है। लेकिन जैसे ही मैं img->setPixel() पर कॉल करता हूं, पॉइंटर शून्य हो जाता है और img->width() रिटर्न 0

तो मैं गलत क्या कर रहा हूं? या पिक्सेल स्तर पर बड़ी छवियों को संशोधित करने का एक बेहतर तरीका है?

सादर, डेविड

+0

आवंटन वास्तव में काम कर रहा है या नहीं, यह देखने के लिए पहले malloc'd स्मृति को मैन्युअल रूप से शून्य करने का प्रयास करें। –

+0

इस पर एक नज़र डालें: [क्यूटी परियोजना विकी: बड़ी छवियां लोड हो रही हैं] (http://qt-project.org/wiki/LoadingLargeImages) – dschulz

+0

याद रखें कि 32 बिट विंडोज़ एप्लिकेशन पर डिफ़ॉल्ट सबसे बड़ा आवंटन आप परिणाम दे सकते हैं पता स्थान विखंडन/LARGEADDRESSAWARE लिंकर ध्वज और/या विखंडन को कम करने के लिए आपके एप्लिकेशन द्वारा उपयोग किए जाने वाले डीएलएस को पुन: उपयोग किए बिना 1.2 जीबी (2 जीबी एप्लिकेशन एड्रेस स्पेस का) होगा। – drescherjm

उत्तर

1

आपका दूसरा दृष्टिकोण जाने का सही तरीका है। जब आप setPixel() पर कॉल करते हैं, तो QImage आपके द्वारा प्रदान किए गए बाहरी बफर की एक प्रति बनाता है और इसके लिए स्मृति से बाहर चला जाता है।

सीधे आपूर्ति किए गए बफर में पिक्सेल मान को बदलने का प्रयास करें। लाइन के बफर में पॉइंटर प्राप्त करने के लिए आप scanLine() का उपयोग कर सकते हैं। मैं setPixel() का उपयोग नहीं करता क्योंकि वैसे भी यह वास्तव में धीमा है।

+0

ठीक है, धन्यवाद। मैं स्कैनलाइन() पर एक नज़र डालेगा। –

4

QImage 32768x32768 पिक्सल छवियों (लघु हस्ताक्षर किए) की एक अधिकतम समर्थन करता है। यह स्थिति से निम्न है: चौड़ाई * ऊंचाई * colordepth < INT_MAX (4 अरब) -> 32768 * 32768 * 4 = 4 अरब। दूसरी शर्त निश्चित रूप से है कि malloc अनुरोधित स्मृति आवंटित करने में सक्षम है।

यदि आपको वास्तव में बड़ी छवियों की आवश्यकता है तो आपको एक और रैपर का उपयोग करना होगा या एकाधिक QImage में विभाजित करना होगा।

2

मैंने समस्या को ट्रैक किया। मैं बस लिंकर विकल्पों में /LARGEADDRESSAWARE ध्वज जोड़ने के लिए भूल गया।

मैंने स्कैनलाइन() संकेत के साथ स्टीफन चु के जवाब की भी सराहना की। सबसे पहले यह कुछ स्मृति बचाता है, दूसरा यह वास्तव में बहुत तेज़ है।

अब मैं सुरक्षित रूप से 32000x16000 पिक्सेल तक छवियां बना सकता हूं जो मेरा वांछित उद्देश्य था।

संबंधित मुद्दे