Base64 के साथ एक छवि फ़ाइल एन्कोडिंग


161

मैं बेस 64 मॉड्यूल का उपयोग करके एक छवि को एक स्ट्रिंग में एन्कोड करना चाहता हूं। मैं हालांकि एक समस्या में भाग गया हूं। मैं जिस छवि को एन्कोडेड करना चाहता हूं, उसे कैसे निर्दिष्ट करूं? मैंने निर्देशिका को छवि का उपयोग करने की कोशिश की, लेकिन यह केवल निर्देशिका को एन्कोड किया गया। मैं चाहता हूं कि वास्तविक छवि फ़ाइल एन्कोड की जाए।

संपादित करें

मैंने इस स्निपेट को आज़माया:

with open("C:\Python26\seriph1.BMP", "rb") as f:
    data12 = f.read()
    UU = data12.encode("base64")
    UUU = base64.b64decode(UU)

    print UUU

    self.image = ImageTk.PhotoImage(Image.open(UUU))

लेकिन मुझे निम्नलिखित त्रुटि मिलती है:

Traceback (most recent call last):
  File "<string>", line 245, in run_nodebug
  File "C:\Python26\GUI1.2.9.py", line 473, in <module>
    app = simpleapp_tk(None)
  File "C:\Python26\GUI1.2.9.py", line 14, in __init__
    self.initialize()
  File "C:\Python26\GUI1.2.9.py", line 431, in initialize
    self.image = ImageTk.PhotoImage(Image.open(UUU))
  File "C:\Python26\lib\site-packages\PIL\Image.py", line 1952, in open
    fp = __builtin__.open(fp, "rb")
TypeError: file() argument 1 must be encoded string without NULL bytes, not str

मैं क्या गलत कर रहा हूं?

जवाबों:


299

मुझे यकीन नहीं है कि मैं आपके सवाल को समझ सकता हूँ। मुझे लगता है आप कुछ की तर्ज पर कर रहे हैं:

import base64

with open("yourfile.ext", "rb") as image_file:
    encoded_string = base64.b64encode(image_file.read())

आपको सबसे पहले फ़ाइल को खोलना होगा, और इसकी सामग्री को पढ़ना होगा - आप केवल एनकोड फ़ंक्शन के लिए पथ को पारित नहीं कर सकते।

संपादित करें: ठीक है, अपने मूल प्रश्न को संपादित करने के बाद यहां एक अपडेट है।

सबसे पहले, कच्चे तार का उपयोग करना याद रखें (गलती से 'आर' के साथ स्ट्रिंग को उपसर्ग करें), विंडोज पर पथ के सीमांकक का उपयोग करते समय, गलती से एक भागने चरित्र को रोकने के लिए। दूसरा, PIL की Image.open या तो एक फ़ाइल नाम, या एक फाइल-लाइक को स्वीकार करता है (अर्थात, ऑब्जेक्ट को रीड, सीक और मेथड्स को बताना है)।

कहा जा रहा है, आप मेमोरी बफर से ऐसी वस्तु बनाने के लिए cStringIO का उपयोग कर सकते हैं:

import cStringIO
import PIL.Image

# assume data contains your decoded image
file_like = cStringIO.StringIO(data)

img = PIL.Image.open(file_like)
img.show()

1
धन्यवाद, एक और समस्या जब मैं डिकोड की गई छवि को प्रिंट करता हूं तो मुझे स्ट्रिंग '.à' मिलती है। हालाँकि, जब मैं इसे अकेले डेटा के विकल्प के रूप में चलाता हूं तो मुझे एक त्रुटि मिलती है। एन्कोडेड स्ट्रिंग तुलना के लिए बहुत लंबा है। इसलिए मुझे लगता है कि संभावना छवि डेटा को संग्रहीत करती है। डिकोडेड स्ट्रिंग केवल एन्कोडेड स्ट्रिंग या कुछ और का संदर्भ देता है? यह डेटा भंडारण के लिए बहुत छोटा लगता है।
रेक्टैंग्लेंगल

मुद्रित आउटपुट आवश्यक रूप से वास्तविक सामग्री के बराबर नहीं है - यह इस बात पर निर्भर करता है कि आप इसे कैसे और कहां प्रिंट करते हैं।
जिम ब्रिसोम

8
मेरे मामले में, मुझे डीकोड करने की आवश्यकता है: base64.b64encode(fh.read()).decode()html फ़ाइलों में उपयोग किए जाने वाले स्ट्रिंग को प्राप्त करने के लिए।
QED

1
base64.b64encode (fh.read ())। डीकोड () सूक्ष्म है, लेकिन मुझे इसकी आवश्यकता है @qed, धन्यवाद। अंतर एक रिटर्न बाइट्स और अन्य स्ट्रिंग है ... और मेरा SOAP सर्वर बिना डिकोडिंग के इसे निगलेगा नहीं!
zzart

57

अजगर 2.x के साथ, आप सामान्य रूप से .encode का उपयोग कर सांकेतिक शब्दों में बदलना कर सकते हैं:

with open("path/to/file.png", "rb") as f:
    data = f.read()
    print data.encode("base64")

12

पहला उत्तर उपसर्ग ख के साथ एक स्ट्रिंग मुद्रित करेगा '। इसका मतलब है कि आपका स्ट्रिंग इस b'your_string की तरह होगा 'इस समस्या को हल करने के लिए कृपया निम्न कोड की कोड जोड़ें।

encoded_string= base64.b64encode(img_file.read())
print(encoded_string.decode('utf-8'))

2
यह एक अच्छे उत्तर की तरह दिखता है, लेकिन कृपया पोस्ट करने से बचना चाहिए यदि उद्देश्य आपकी वेबसाइट को बढ़ावा देना है। हालाँकि, आपकी प्रोफ़ाइल में लिंक जोड़ने के लिए आपका स्वागत है।
रोकें

1
(संयोग से, उत्तर आदेश यहां पर भरोसा नहीं किया जा सकता है, इसलिए यह "पहले उत्तर" जैसी टिप्पणियों से बचने के लायक है। जो पहले दिखाई देता है वह समय के साथ बदल सकता है। :-))
रोकें

इस उत्तर के अपने मूल संस्करण में, ऐसा लगता है कि आप अपनी स्वयं की साइट या किसी ऐसी साइट से जुड़े हैं, जिसके साथ आप संबद्ध हैं। यदि आप ऐसी साइट से लिंक करते हैं, तो आपको यह बताना होगा कि यह आपकी साइट है । यदि आप संबद्धता का खुलासा नहीं करते हैं, तो इसे स्पैम माना जाता है। देखें: क्या "अच्छा" आत्म प्रचार दर्शाता है? और स्व-प्रचार पर सहायता केंद्र । प्रकटीकरण स्पष्ट होना चाहिए, लेकिन औपचारिक होने की आवश्यकता नहीं है। यह अपनी खुद की है जब व्यक्तिगत सामग्री, यह सिर्फ तरह कुछ हो सकता है, "अपने ब्लॉग पर ...", आदि "मेरी साइट ... पर"
Makyen

सुझाव के लिए धन्यवाद @ मैकिने मैं खुलासा करने जा रहा हूं कि यह मेरी साइट है। क्या यह खुलासा करने के लिए कि अब यह मेरी साइट है, इसका जवाब देना कानूनी होगा? या मुझे इसे संपादित नहीं करना चाहिए।
कोडस्पेडी

9

जैसा कि मैंने आपके पिछले प्रश्न में कहा था, स्ट्रिंग को एनकोड करने की कोई आवश्यकता नहीं है, यह केवल प्रोग्राम को धीमा कर देगा। बस repr का उपयोग करें

>>> with open("images/image.gif", "rb") as fin:
...  image_data=fin.read()
...
>>> with open("image.py","wb") as fout:
...  fout.write("image_data="+repr(image_data))
...

अब छवि को एक चर के रूप में संग्रहीत किया जाता image_dataहै जिसे एक फ़ाइल में बुलाया जाता है जिसे image.py एक ताज़ा दुभाषिया प्रारंभ करें और छवि_डेटा आयात करें

>>> from image import image_data
>>>

मैं वास्तव में नहीं देखता कि कैसे repr () यहाँ किसी काम का हो सकता है।
इवो ​​वैन डेर विजक

6
@ इवो, एंटीक अजगर छवियों में छवियों को संग्रहीत करने में सक्षम होना चाहता है। मैं इंगित कर रहा हूं कि बेस 64 का उपयोग करना उल्टा है क्योंकि हर बार मॉड्यूल लोड होने पर डेटा को डीकोड करना पड़ता है। इसके बजाय रीप का उपयोग करने का मतलब है कि शाब्दिक स्ट्रिंग तत्काल उपयोग के लिए तैयार है। कोई फ़ाइल नहीं प्रसंस्करण के साथ। फ़ाइल
जॉन ला रोय

7

Ivo van der Wijk और gnibbler से उधार लेना पहले विकसित हो चुका है, यह एक गतिशील समाधान है

import cStringIO
import PIL.Image

image_data = None

def imagetopy(image, output_file):
    with open(image, 'rb') as fin:
        image_data = fin.read()

    with open(output_file, 'w') as fout:
        fout.write('image_data = '+ repr(image_data))

def pytoimage(pyfile):
    pymodule = __import__(pyfile)
    img = PIL.Image.open(cStringIO.StringIO(pymodule.image_data))
    img.show()

if __name__ == '__main__':
    imagetopy('spot.png', 'wishes.py')
    pytoimage('wishes')

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


7
import base64
from PIL import Image
from io import BytesIO

with open("image.jpg", "rb") as image_file:
    data = base64.b64encode(image_file.read())

im = Image.open(BytesIO(base64.b64decode(data)))
im.save('image1.png', 'PNG')

1
यह उत्तर वास्तव में शीर्ष पर होना चाहिए ... सर्वश्रेष्ठ एक - धन्यवाद!
लूथर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.