2011-10-15 17 views
5

मैं एक कोड लिखता हूं जो फ़ाइल से पीएनजी छवि पढ़ता है और नियंत्रण के साथ दिखाता है।
मैं धारा से छवि को पढ़ने चाहते हैं और सेटमेमोरी अपवाद से बाहर। बैकग्राउंड इमेज = छवि। फ्रॉमस्ट्रीम (मेमस्ट्रीम);

control.BackgroundImage = Image.FromStream(memStream); 

लेकिन जब उपयोग इस कोड, तब हो अपवाद "स्मृति से बाहर"। लेकिन जब

control.Image = Image.FromStream(memStream); 

या

control.BackgroundImage = Image.FromFile(fileSource); 

उपयोग करते हैं, कि काम है।

छवि फ़ाइल का आकार 5 केबी है।

if (System.IO.File.Exists(imgSource)) 
{ 
    using (FileStream localFileStream = new FileStream(imgSource, FileMode.Open)) 
    { 
    using (MemoryStream memStream = new MemoryStream()) 
    { 
    int bytesRead; 
    byte[] buffer = new byte[1024]; 

    while ((bytesRead = localFileStream.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     memStream.Write(buffer, 0, bytesRead); 
    } 
    retIMG = Image.FromStream(memStream); 

    pictureBox1.Image = retIMG;  // is work 
    label1.Image = retIMG;  // is work 
    button1.Image = retIMG;  // is work 
    button1.BackgroundImage = retIMG; // don't work 
    groupBox1.BackgroundImage = retIMG; // don't work 
    panel1.BackgroundImage = retIMG; // don't work 
    } 
    } 
} 

मुझे लगता है कि नेट फ्रेमवर्क में एक बग। कृपया मेरी मदद करें?

+0

यह हिस्सा समस्या है? मेरा सुझाव है कि आप छवि को पहले एक चर में रखें, फिर दूसरे ऑपरेशन पर असाइन करें। छवि कितनी बड़ी है? 5ggb फ़ाइल का आकार 50.000x50.000 पिक्सेल हो सकता है;) – TomTom

+1

छवियां गलत होने वाली किसी भी चीज के लिए "मेमोरी आउट" की रिपोर्ट करती हैं। –

+0

जैसे ही हेनक ने कहा, जीडीआई + (और इस प्रकार 'सिस्टम। ड्रॉइंग') कई मामलों में आउटऑफमेमरी त्रुटियों को फेंकता है जहां यह वास्तव में स्मृति से बाहर नहीं है, जैसे अमान्य पैरामीटर। मुझे लगता है कि यह उनमें से एक है। – CodesInChaos

उत्तर

6

डेकैफ़ के सही उत्तर में जोड़ने के लिए कुछ पृष्ठभूमि देना। जीडीआई + बिटमैप के पिक्सल की प्रतिलिपि बनाने से बचने के लिए बहुत मेहनत करता है। यह महंगा है, दर्जन मेगाबाइट लेते हुए बिटमैप असामान्य नहीं है। जब आप बिटमैप कन्स्ट्रक्टर या छवि के साथ किसी फ़ाइल से बिटमैप लोड करते हैं। FromFile() तो GDI + मेमोरी-मैप की गई फ़ाइल बनाता है। पिक्सेल मांग पर पेज-इन होते हैं, केवल तभी जब आवश्यक हो। बहुत कुशल लेकिन यह फ़ाइल पर एक ताला डालता है। स्पष्ट रूप से आप इस कोड में लॉक से बचने की कोशिश कर रहे थे।

आप वास्तव में मेमोरीस्ट्रीम के साथ मेमोरी में बाइट्स लोड करके उस लॉक से बचें। लेकिन एक ही सिद्धांत अभी भी लागू होता है, जीडीआई + अभी भी पिक्सल की प्रतिलिपि नहीं करता है और जब इसे आवश्यकता होती है तो केवल स्ट्रीम से पढ़ता है। जब आप स्ट्रीम() स्ट्रीम करते हैं तो यह गलत हो जाता है। निदान करने के लिए बहुत मुश्किल है क्योंकि अपवाद बाद में होता है, आमतौर पर जब बिटमैप को खींचा जाना आवश्यक होता है। यह पेंटिंग कोड में बम है, आपके पास देखने के लिए कोई कोड नहीं है लेकिन एप्लिकेशन। रुन()। एक क्रैपी अपवाद संदेश के साथ, जीडीआई + में केवल कुछ हद तक त्रुटि कोड हैं। आप मेमोरी से बाहर नहीं हैं, यह केवल जीडीआई + के लिए रास्ता दिखता है, यह अन्यथा यह नहीं समझ सकता कि धारा अचानक क्यों पठनीय नहीं है।

समस्या का कम से कम हिस्सा MemoryStream के बहुत अजीब कार्यान्वयन के कारण होता है। Disis()। निपटान अप्रबंधित संसाधनों को जारी करने के लिए है। एक मेमोरी स्ट्रीम में कोई नहीं है, यह केवल स्मृति का मालिक है।कचरा कलेक्टर द्वारा पहले से ही इसका ख्याल रखा गया है। दुर्भाग्यवश उन्होंने इसे किसी भी तरह लागू किया। वास्तव में कुछ भी निपटाने से नहीं, क्योंकि निपटान करने के लिए कुछ भी नहीं है, लेकिन मेमोरीस्ट्रीम को अपठनीय चिह्नित करके। जो जीडीआई + में त्रुटि को ट्रिगर करता है जब यह बिटमैप ड्राइंग करते समय पढ़ने की कोशिश करता है।

तो अपनी समस्या को हल करने के लिए मेमोरीस्ट्रीम का निपटान करने से बचने के लिए कथन का उपयोग करके को हटा दें। और बिटमैप अब उपयोग में नहीं होने पर इसे बाद में निपटाने के बारे में चिंतित न हों। निपटान करने के लिए कुछ भी नहीं है, कचरा कलेक्टर स्वचालित रूप से स्मृति को मुक्त करता है।

+0

दरअसल 'मेमोरीस्ट्रीम' में 'वेटहैंडल' के रूप में अप्रबंधित संसाधन हो सकते हैं, जो कि 'BeginRead' या' BeginWrite' 'पर लागू किया गया था। यहां कोई समस्या होने की संभावना नहीं है, लेकिन सोचा कि मुझे इसे किसी भी तरह से इंगित करना चाहिए। – DeCaf

+0

सच है। वास्तव में असंभव है। रास्ते में एक बहुत अच्छी पृष्ठभूमि स्पष्टीकरण के लिए –

+1

+1! – DeCaf

7

MSDN पर Image.FromStream पर टिप्पणी पढ़ें:

आप धारा छवि के जीवन भर के लिए खुला रखना चाहिए।

इसलिए यदि आप अपने MemoryStream अपने कोड के निर्माण के चारों ओर using को दूर ठीक काम करता है।

बेशक आप अधिमानतः MemoryStream निपटाने चाहिए एक बार तुम अब, Image आपके द्वारा बनाए जरूरत है हालांकि वहां की संभावना बुला Dispose() नहीं और जीसी करने के लिए इसे छोड़ रहा है यह एक बार अप्रयुक्त एकत्र करने के लिए इस मामले में कोई नुकसान नहीं है।

तथ्य यह है कि ऐसा लगता है कि यह आपके कुछ कोड के साथ काम करता है, वह संभवतः शुद्ध भाग्य है और इसे एक समाधान समाधान नहीं माना जाना चाहिए। इस तरह quirks के बारे में पता लगाने के लिए हमेशा दस्तावेज पढ़ें।

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