2012-05-04 16 views
5

के साथ आरजीबीए बिटमैप लोड करें मैंने पीआईएल का उपयोग कर 32-बिट बिटमैप को 32-बिट पीएनजी में बदलने की कोशिश की।पीआईएल

from PIL import Image 
im = Image.open('example.bmp') 
print im.mode 
# it prints 'RGB', but expected was 'RGBA' 
im.save('output.png', format='PNG') 

अपेक्षित छवि मोड 'आरजीबीए' है, लेकिन वास्तव में मुझे 'आरजीबी' मिलता है।

मैंने निम्नलिखित कोड भी आजमाया, लेकिन यह काम नहीं करता है।

from PIL import Image 
im = Image.open('example.bmp') 
im = im.convert('RGBA') 
im.save('output.png', format='PNG') 
+1

मुझे लगता है कि 32-बिट बिटमैप फ़ाइल एक गैर-मानक प्रारूप है जो पीआईएल का समर्थन नहीं करता है। .bmp पर एक आरजीबीए छवि लिखने की कोशिश कर त्रुटि उत्पन्न करता है 'मोड आरजीबीए को बीएमपी के रूप में नहीं लिख सकता'। –

उत्तर

3

ठीक है, यहां कुछ शुरू करने के लिए कुछ है। चूंकि मुझे विशेष रूप से पता नहीं है कि आपकी बीएमपी फ़ाइल कौन सा प्रारूप है, मैंने केवल पूर्ण अल्फा चैनल के साथ बीएमपी का एक विशिष्ट मामला संभाला है जो मेरे पास है। मैं जिस तरह से बीएमपी का प्रबंधन कर रहा हूं उसे परिवर्तित करके प्राप्त किया जा सकता है, उदाहरण के लिए, छवि मैगिक का उपयोग करके बीएमपी के अल्फा के साथ पीएनजी। यह "BITMAPV5" कहलाता है। आपके विवरण को देखते हुए, आपके पास बिटमैपवी 5 नहीं है (क्योंकि पीआईएल इसे खोलने में भी असफल होगा), इसलिए हमें आपके विशिष्ट मामले को हल करने के लिए चर्चाओं के साथ पुनरावृत्ति की आवश्यकता होगी।

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

from PIL import ImageFile, BmpImagePlugin 

_i16, _i32 = BmpImagePlugin.i16, BmpImagePlugin.i32 

class BmpAlphaImageFile(ImageFile.ImageFile): 
    format = "BMP+Alpha" 
    format_description = "BMP with full alpha channel" 

    def _open(self): 
     s = self.fp.read(14) 
     if s[:2] != 'BM': 
      raise SyntaxError("Not a BMP file") 
     offset = _i32(s[10:]) 

     self._read_bitmap(offset) 

    def _read_bitmap(self, offset): 

     s = self.fp.read(4) 
     s += ImageFile._safe_read(self.fp, _i32(s) - 4) 

     if len(s) not in (40, 108, 124): 
      # Only accept BMP v3, v4, and v5. 
      raise IOError("Unsupported BMP header type (%d)" % len(s)) 

     bpp = _i16(s[14:]) 
     if bpp != 32: 
      # Only accept BMP with alpha. 
      raise IOError("Unsupported BMP pixel depth (%d)" % bpp) 

     compression = _i32(s[16:]) 
     if compression == 3: 
      # BI_BITFIELDS compression 
      mask = (_i32(self.fp.read(4)), _i32(self.fp.read(4)), 
        _i32(self.fp.read(4)), _i32(self.fp.read(4))) 
      # XXX Handle mask. 
     elif compression != 0: 
      # Only accept uncompressed BMP. 
      raise IOError("Unsupported BMP compression (%d)" % compression) 

     self.mode, rawmode = 'RGBA', 'BGRA' 

     self.size = (_i32(s[4:]), _i32(s[8:])) 
     direction = -1 
     if s[11] == '\xff': 
      # upside-down storage 
      self.size = self.size[0], 2**32 - self.size[1] 
      direction = 0 

     self.info["compression"] = compression 

     # data descriptor 
     self.tile = [("raw", (0, 0) + self.size, offset, 
      (rawmode, 0, direction))] 

ठीक से इस का उपयोग करने के लिए, विहित तरीका माना जाता है कि प्रदर्शन करने के लिए है:

from PIL import Image 
Image.register_open(BmpAlphaImageFile.format, BmpAlphaImageFile) 
# XXX register_save 

Image.register_extension(BmpAlphaImageFile.format, ".bmp") 

समस्या पहले से ही ".bmp से निपटने के लिए एक प्लगइन है कि वहाँ है ", और मुझे यह पता लगाने में कोई दिक्कत नहीं हुई कि मैं इस नए एक्सटेंशन को कैसे प्रीपेड कर सकता हूं, इसलिए इसका उपयोग बीएमपीइमेज प्लगइन से पहले किया जाता है (मुझे यह भी नहीं पता कि पीआईएल में ऐसी चीज करना संभव है या नहीं)। ने कहा कि, मैं वास्तव में कोड सीधे, में के रूप में इस्तेमाल:

from BmpAlphaImagePlugin import BmpAlphaImageFile 

x = BmpAlphaImageFile('gearscolor.bmp') 
print x.mode 
x.save('abc1.png') 

कहाँ gearscolor.bmp पहले वर्णित पूर्ण अल्फ़ा चैनल के साथ एक नमूना बिटमैप है। परिणामी पीएनजी अल्फा डेटा के साथ सहेजा गया है। यदि आप BmpImagePlugin.py के कोड की जांच करते हैं, तो आप देखेंगे कि मैंने इसके अधिकांश कोड का पुन: उपयोग किया है।

+0

मुझे एक त्रुटि मिली "मेरी बिटमैप फ़ाइल – stanleyxu2005

+0

के लिए असमर्थित बीएमपी हेडर प्रकार (40)" मैं इसकी अपेक्षा कर रहा था। क्या आप कहीं भी अपना सटीक बीएमपी अपलोड कर सकते हैं? – mmgp

+0

अद्यतन कोड देखें, मुझे आपकी फ़ाइल प्रारूप को संभालने के लिए कुछ भी बदलने की आवश्यकता नहीं है। – mmgp

0

पीआईएल छोटी है और पारदर्शी बीएमपी फाइलों के साथ ठीक से काम नहीं करता है।

यदि मुझे अच्छी तरह याद है तो wxPython उनके साथ ठीक से काम करता प्रतीत होता है। मैंने एक साल पहले दोनों के बीच एक छोटा सा रैपर लिखा था, केवल तभी जब मैं कोड पा सकूं।