2010-05-28 12 views
6

क्या छवि के आकार पर कोई सीमा है जिसे .NET से उपलब्ध छवि फ़ाइल कोडेक्स का उपयोग करके एन्कोड किया जा सकता है?.NET GDI + छवि आकार - फ़ाइल कोडेक सीमाएं

मैं छवियों को 4 जीबी आकार में एन्कोड करने की कोशिश कर रहा हूं, लेकिन यह बस काम नहीं करता है (या ठीक से काम नहीं करता है यानी एक अपठनीय फ़ाइल लिखता है) .bmp, .jpg, .png या .tif एन्कोडर्स के साथ।

जब मैं छवि आकार को < 2GB पर कम करता हूं तो यह .jpg के साथ काम करता है लेकिन .bmp, .tif या .png नहीं।

मेरा अगला प्रयास libtiff का प्रयास करना होगा क्योंकि मुझे पता है कि टिफ फाइलें बड़ी छवियों के लिए हैं।

बड़ी छवियों के लिए एक अच्छा फ़ाइल प्रारूप क्या है? या मैं सिर्फ फाइल प्रारूप सीमाओं को मार रहा हूँ?

(यह सब x64 वास्तुकला का प्रयोग डब्ल्यू रैम/8 जीबी एक 64 बिट ऑपरेटिंग सिस्टम (WinXP 64) पर किया जा रहा है और संकलित।)

Random r = new Random((int)DateTime.Now.Ticks); 

int width = 64000; 
int height = 64000; 
int stride = (width % 4) > 0 ? width + (width % 4) : width; 
UIntPtr dataSize = new UIntPtr((ulong)stride * (ulong)height); 
IntPtr p = Program.VirtualAlloc(IntPtr.Zero, dataSize, Program.AllocationType.COMMIT | Program.AllocationType.RESERVE, Program.MemoryProtection.READWRITE); 

Bitmap bmp = new Bitmap(width, height, stride, PixelFormat.Format8bppIndexed, p); 
BitmapData bd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat); 

ColorPalette cp = bmp.Palette; 
for (int i = 0; i < cp.Entries.Length; i++) 
{ 
    cp.Entries[i] = Color.FromArgb(i, i, i); 
} 
bmp.Palette = cp; 

unsafe 
{ 
    for (int y = 0; y < bd.Height; y++) 
    { 
    byte* row = (byte*)bd.Scan0.ToPointer() + (y * bd.Stride); 
    for (int x = 0; x < bd.Width; x++) 
    { 
     *(row + x) = (byte)r.Next(256); 
    } 
    } 
} 

bmp.UnlockBits(bd); 
bmp.Save(@"c:\test.jpg", ImageFormat.Jpeg); 
bmp.Dispose(); 

Program.VirtualFree(p, UIntPtr.Zero, 0x8000); 

मैं भी एक पिन किए गए जीसी स्मृति का उपयोग की कोशिश की है क्षेत्र, लेकिन यह < 2 जीबी तक सीमित है।

Random r = new Random((int)DateTime.Now.Ticks); 

int bytesPerPixel = 4; 
int width = 4000; 
int height = 4000;   
int padding = 4 - ((width * bytesPerPixel) % 4); 
padding = (padding == 4 ? 0 : padding); 
int stride = (width * bytesPerPixel) + padding; 
UInt32[] pixels = new UInt32[width * height]; 
GCHandle gchPixels = GCHandle.Alloc(pixels, GCHandleType.Pinned); 
using (Bitmap bmp = new Bitmap(width, height, stride, PixelFormat.Format32bppPArgb, gchPixels.AddrOfPinnedObject())) 
{ 
    for (int y = 0; y < height; y++) 
    { 
     int row = (y * width); 
     for (int x = 0; x < width; x++) 
     { 
      pixels[row + x] = (uint)r.Next(); 
     } 
    } 

    bmp.Save(@"c:\test.jpg", ImageFormat.Jpeg); 
} 
gchPixels.Free(); 
+0

आप किस प्रोसेसर आर्किटेक्चर का उपयोग कर रहे हैं? –

+0

@ रोवलैंड - x64 का उपयोग करके संकलित।तो 64 बिट। मुझे नहीं लगता कि इतनी बड़ी छवियों के लिए 32 बिट पर्याप्त होगा। मेरी मशीन में 8 जीबी रैम है, शायद यह पर्याप्त नहीं है हालांकि यह 4 जीबी से थोड़ा अधिक छवि के लिए होना चाहिए। मेरे पास लगभग 7 जीबी मुफ्त है, जब एन्कोडर वहां पर आता है तो अभी भी 1-2 जीबी मुफ्त है। –

+0

@roygbiv बस स्पष्ट जांच रहा है :) –

उत्तर

2

समस्या आप का सामना कर रहे बहुत संभावना .NET फ्रेमवर्क में निम्नलिखित सीमा है: अधिकतम ऑब्जेक्ट आकार जीसी ढेर में अनुमति दी 2GB है, यहां तक ​​कि 64-बिट ओएस/बनाता है पर।

कुछ संदर्भ: link, link, link

टीआईएफएफ जैसे अपेक्षाकृत सरल (असम्पीडित) प्रारूप के साथ आपकी आवश्यकताओं के आधार पर भागों में अपनी छवि उत्पन्न करने और बाद में भागों को मर्ज करने के लिए करने योग्य हो सकता है। बस एक विचार ..

+0

जैसा कि मैंने इंगित किया है, मैं वर्चुअल अलार्म का उपयोग मेमोरी बिटमैप्स> 4 जीबी में बनाने के लिए कर सकता हूं, हालांकि, विभिन्न एन्कोडर्स ऐसी छवियों को डिस्क पर लिखने में विफल रहते हैं। यदि आप सुझाव दे रहे हैं कि एन्कोडर को केवल 2 जीबी रैम की आवश्यकता है तो मुझे नहीं लगता कि यह एक बहुत ही कुशल एन्कोडर है। –

+1

मैंने कोड को तेज़ी से स्किम किया, लेकिन आपको परीक्षण करना चाहिए कि बिटमैप। सेव फ़ाइल को इसे फिर से लिखने से पहले स्मृति (फिर से) में बनाने के लिए कोशिश करता है (शायद यह करता है)। इससे व्यवहार की व्याख्या होगी ... – ChristopheD

+0

मैं इसे फिर से चलाउंगा, लेकिन ऐसा लगता है कि यह इसे सहेजने से पहले छवि का पुनर्निर्माण नहीं करता है। –

1
TIFF विनिर्देश धारा 2 से

: पर TIFF संरचना http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf पर:

TIFF एक छवि फ़ाइल स्वरूप है। इस दस्तावेज़ में, फ़ाइल को 8-बिट बाइट्स के अनुक्रम के रूप में परिभाषित किया गया है, जहां बाइट 0 से एन तक गिने जाते हैं। सबसे बड़ी संभव टीआईएफएफ फ़ाइल 2 ** 32 लंबाई में बाइट्स है।

दुर्भाग्यवश कई टीआईएफएफ लेखकों और पाठक कार्यान्वयन में हस्ताक्षरित पूर्णांक का उपयोग करते हैं और व्यावहारिक आकार को 2 ** 31 तक कम करते हैं। यह क्रिस्टोफ़ द्वारा उल्लिखित स्मृति में पूरी छवि को स्मृति में रखने के लिए ड्राइवरों द्वारा लगातार प्रयास द्वारा मिश्रित किया जाता है।

आपको 80 के दशक या उससे पहले के अन्य छवि प्रारूपों में समान सीमाएं मिल सकती हैं। मल्टी गीगाबाइट फ़ाइल आकार सीमा को समस्या नहीं माना गया था जब डिस्क केवल मेगाबाइट के दसियों में थीं।

1

तो आपका लक्ष्य उन्हें जेपीईजी में एन्कोड करना है? मुझे यकीन है कि केवल उस अनुभाग को खींचने का एक तरीका होगा जिसे आप एन्कोडिंग कर रहे हैं, फिर निपटान करें और अगले खंड पर जाएं। यदि आप फ़ाइल को कच्चे खोलते हैं और इसे स्वयं पार्स करते हैं, तो मुझे यकीन है कि अनुभाग बनाने में सहायता के लिए ओपन सोर्स जेपीईजी एन्कोडर्स हैं। यह आपको फ़ाइलों को बहुत बड़ी एन्कोड करने की अनुमति दे सकता है, लेकिन आपके पास हमेशा ओएस और फाइल सिस्टम बाधाओं को दूर करने के लिए बाधा होगी।

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