I want to encode an image into a string using the base64 module. I’ve ran into a problem though. How do I specify the image I want to be encoded? I tried using the directory to the image, but that simply leads to the directory being encoded. I want the actual image file to be encoded.
I tried this snippet:
with open("C:Python26seriph1.BMP", "rb") as f: data12 = f.read() UU = data12.encode("base64") UUU = base64.b64decode(UU) print UUU self.image = ImageTk.PhotoImage(Image.open(UUU))
but I get the following error:
Traceback (most recent call last): File "<string>", line 245, in run_nodebug File "C:Python26GUI1.2.9.py", line 473, in <module> app = simpleapp_tk(None) File "C:Python26GUI1.2.9.py", line 14, in __init__ self.initialize() File "C:Python26GUI1.2.9.py", line 431, in initialize self.image = ImageTk.PhotoImage(Image.open(UUU)) File "C:Python26libsite-packagesPILImage.py", line 1952, in open fp = __builtin__.open(fp, "rb") TypeError: file() argument 1 must be encoded string without NULL bytes, not str
What am I doing wrong?
I’m not sure I understand your question. I assume you are doing something along the lines of:
import base64 with open("yourfile.ext", "rb") as image_file: encoded_string = base64.b64encode(image_file.read())
You have to open the file first of course, and read its contents – you cannot simply pass the path to the encode function.
Ok, here is an update after you have edited your original question.
First of all, remember to use raw strings (prefix the string with ‘r’) when using path delimiters on Windows, to prevent accidentally hitting an escape character. Second, PIL’s Image.open either accepts a filename, or a file-like (that is, the object has to provide read, seek and tell methods).
That being said, you can use cStringIO to create such an object from a memory buffer:
import cStringIO import PIL.Image # assume data contains your decoded image file_like = cStringIO.StringIO(data) img = PIL.Image.open(file_like) img.show()
The first answer will print a string with prefix b’.
That means your string will be like this b’your_string’ To solve this issue please add the following line of code.
encoded_string= base64.b64encode(img_file.read()) print(encoded_string.decode('utf-8'))
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')
As I said in your previous question, there is no need to base64 encode the string, it will only make the program slower. Just use the 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)) ...
Now the image is stored as a variable called
image_data in a file called
Start a fresh interpreter and import the image_data
from image import image_data >>>
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')
You can then decide to compile the output image file with Cython to make it cool. With this method, you can bundle all your graphics into one module.