2010-06-25 16 views
5

लोड करते समय स्मृति त्रुटि से बाहर मैं बड़े आकार की छवियों (पूर्व 16000x9440 पीएक्स के लिए) के साथ काम कर रहा हूं और अन्य चीजों के लिए कुछ क्षेत्रों में कटौती करता हूं। सब काम ठीकबिटमैप

using (FileStream fileStream = new FileStream(mapFileResized, FileMode.Open)) 
{ 
    byte[] data = new byte[fileStream.Length]; 
    fileStream.Read(data, 0, data.Length); 
    using (MemoryStream memoryStream = new MemoryStream(data)) 
    { 
     using (Bitmap src = new Bitmap(memoryStream)) // <-- exception 
     { 
      tile = new Bitmap(tileWidth, tileHeight, PixelFormat.Format24bppRgb); 
      tile.SetResolution(src.HorizontalResolution, src.VerticalResolution); 
      tile.MakeTransparent(); 
      using (Graphics grRect = Graphics.FromImage(tile)) 
      { 
       grRect.CompositingQuality = CompositingQuality.HighQuality; 
       grRect.SmoothingMode = SmoothingMode.HighQuality; 
       grRect.DrawImage(
         src, 
         new RectangleF(0, 0, tileWidth, tileHeight), 
         rTile, 
         GraphicsUnit.Pixel 
       ); 
      } 
     } 
    } 
} 

जब मैं छोटा छवि आकार का उपयोग तो: मैं एक अपवाद हो रही है "स्मृति समाप्त" जब एक नया बिटमैप उदाहरण बनाने (पूर्व के लिए 8000x4720 पिक्सल।)।

मैं बड़े आकार की छवियों के साथ कैसे काम कर सकता हूं?

पीएस टाइल बिटमैप अंततः ब्लॉक में निपटाया गया है।

सर्वश्रेष्ठ संबंध, एलेक्स।

उत्तर

3
नहीं

आपके सवाल का पूरा जवाब है, लेकिन आप ImageMagick.NET

+0

यह वही समस्या है। –

+0

आर्किटेक्चर पेज के अनुसार (http://www.imagemagick.org/script/architecture.php#tera-pixel) ImageMagick मेगा-, गीगा-, या टेरा-पिक्सेल छवि आकार को "पढ़, संसाधित या लिख ​​सकता है।" हालांकि यह कोशिश नहीं की है। –

2

MemoryStream की तरह एक पुस्तकालय का उपयोग करने का शायद बेहतर बाइट्स कि डेटा संग्रहीत करता है की एक सरणी का उपयोग कर कार्यान्वित किया जाता है कर रहे हैं। यदि आप सरणी से अधिक डेटा पढ़ सकते हैं, तो डबल आकार की एक नई सरणी आवंटित की जाती है और बाइट एक सरणी से दूसरे में कॉपी की जाती हैं।

चूंकि आप स्पष्ट रूप से जानते हैं कि आपको कितना डेटा चाहिए, आप सही आकार को आगे आवंटित कर सकते हैं और इस प्रकार आकार बदलने से बच सकते हैं।

हालांकि, एक बार जब आप एक निश्चित आकार तक पहुंच जाते हैं तो आप स्मृति से बाहर हो जाएंगे। .NET एक ऑब्जेक्ट पर एक 2 जीबी सीमा लगाता है (even on 64 bit), इसलिए MemoryStream में आंतरिक सरणी कभी भी इससे आगे बढ़ने में सक्षम नहीं होगी। यदि आपकी छवि उस से बड़ी है तो आपको स्मृति अपवाद से बाहर निकलना होगा।

6

आप रैम के गीगाबाइट के बारे में उपयोग कर रहे हैं, यह बहुत आश्चर्यजनक नहीं है कि आप स्मृति से बाहर निकलते हैं।

मान लिया जाये कि आप 16000x9440 पिक्सेल के साथ एक 32bpp fileformat का उपयोग आप के बारे में की एक फ़ाइल आकार मिलता है:

16000 * 9440 * (32/8) = ~ 576MB

byte[] data = new byte[fileStream.Length]; 
fileStream.Read(data, 0, data.Length); 
using (MemoryStream memoryStream = new MemoryStream(data)) 
{ 
    [... snip ...] 
} 

तुम एक में पूरी फाइल लोड मेमोरी स्ट्रीम, इसके लिए 576 एमबी की आवश्यकता है।

[... snip ...] 
    using (Bitmap src = new Bitmap(memoryStream)) // <-- exception 
    { 
     [... snip ...] 
    } 
[... snip ...] 

आप एक बिटमैप में पूरी धारा सामग्री लोड, यह कम से कम एक और 576MB की आवश्यकता है (पर कितनी स्मृति बिटमैप प्रति पिक्सेल की आवश्यकता है निर्भर करता है, कम से कम 4, propably अधिक होना चाहिए)। उस समय आपके पास स्मृति में दो बार छवि है जो ऐसी बड़ी छवियों के लिए गंभीरता से दर्द करती है।

आप मेमोरी स्ट्रीम से छुटकारा पाने और फ़ाइल स्ट्रीम से सीधे बिटमैप लोड करके मेमोरी पदचिह्न को कम कर सकते हैं।

एक और समाधान बिटमैप का केवल एक हिस्सा लोड करना होगा और मांग पर अन्य हिस्सों को लोड करना होगा (Google मानचित्र की तरह), लेकिन मैं उस समाधान के साथ आपकी सहायता नहीं कर सकता, शायद बिटमैप को मैन्युअल रूप से पढ़ने की आवश्यकता हो सकती है।

+0

+1, समस्या को समझाने के अलावा, विकल्पों की पेशकश के बगल में +1। सलाह के लिए – Aistina

+0

Thx, मैंने मेमोरीस्ट्रीम घोषणा को हटा दिया और फ़ाइल से सीधे बिटमैप लोड किया है स्ट्रीम: (बिटमैप src = new बिटमैप (फ़ाइलस्ट्रीम)) का उपयोग कर। लेकिन इससे मदद नहीं मिली = (मेरे पास विंडोज 7 x64 और 5 जीबी से अधिक वीआरएएम मुक्त है। आंशिक रूप से लोडिंग प्रक्रिया के साथ समाधान अच्छा लगता है, शायद यह सहायक हो सकता है। –

+1

यह इसे समझा नहीं है, ए। नेट प्रोग्राम आसानी से स्मृति के 1 गीगाबाइट से अधिक आवंटित कर सकता है। –

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