I tested it only with base64 image embeded in HTML file but it should be the same.
You have to read image as bytes, encode to base64, convert it to string and then use in
'<img src="data:image/jpeg;base64,' + data_base64 + '">'
Working example to embed base64 image in HTML file:
import base64
data = open('image.jpg', 'rb').read() # read bytes from file
data_base64 = base64.b64encode(data) # encode to base64 (bytes)
data_base64 = data_base64.decode() # convert bytes to string
print(data_base64)
#html = '<html><body><img src="data:image/jpeg;base64,' + data_base64 + '"></body></html>' # embed in html
html = '<img src="data:image/jpeg;base64,' + data_base64 + '">' # embed in html
open('output.html', 'w').write(html)
Example encode and decode base64 image
Answer from furas on Stack OverflowPython 3 image base64 without saving into html img tag - Stack Overflow
how to encode image to base64 in python and insert to HTML? - Stack Overflow
Create PNG from base64 encoded html.Img src
django - Python encode an image in base 64 after a html upload - Stack Overflow
This should do it in Python:
import base64
binary_fc = open(filepath, 'rb').read() # fc aka file_content
base64_utf8_str = base64.b64encode(binary_fc).decode('utf-8')
ext = filepath.split('.')[-1]
dataurl = f'data:image/{ext};base64,{base64_utf8_str}'
Thanks to @cnst comment, we need the prefix data:image/{ext};base64,
Thanks to @ramazanpolat answer, we need the decode('utf-8')
In python3, base64.b64encode returns a bytes instance, so it's necessary to call decode to get a str, if you are working with unicode text.
# Image data from [Wikipedia][1]
>>>image_data = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x05\x00\x00\x00\x05\x08\x06\x00\x00\x00\x8do&\xe5\x00\x00\x00\x1cIDAT\x08\xd7c\xf8\xff\xff?\xc3\x7f\x06 \x05\xc3 \x12\x84\xd01\xf1\x82X\xcd\x04\x00\x0e\xf55\xcb\xd1\x8e\x0e\x1f\x00\x00\x00\x00IEND\xaeB`\x82'
# String representation of bytes object includes leading "b" and quotes,
# making the uri invalid.
>>> encoded = base64.b64encode(image_data) # Creates a bytes object
>>> 'data:image/png;base64,{}'.format(encoded)
"data:image/png;base64,b'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='"
# Calling .decode() gets us the right representation
>>> encoded = base64.b64encode(image_data).decode('ascii')
>>> 'data:image/png;base64,{}'.format(encoded)
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
If you are working with bytes directly, you can use the output of base64.b64encode without further decoding.
>>> encoded = base64.b64encode(image_data)
>>> b'data:image/png;base64,' + encoded
b'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
I'm probably too late to the party here, but I just stumbled across this and it sounds to me like an issue with the file's seek position. If image_lookup() reads the file (or causes the file to be read), it may leave the seek position at the end of the file. Subsequent reads of the file (from that position) therefore return nothing.
This makes sense given that commenting out the image_lookup() call, and making a copy of the file instance prior to making the call, both worked. If it is indeed the case, seeking the file back to the start is all you need to do, which is as simple as: file.seek(0).
This is untested, but should be all you need:
c = Client(cId, sId)
c.get_token()
tags = c.image_lookup(imageUploaded)
# Seek file back to the beginning
imageUploaded.seek(0)
urlImage = base64.b64encode(imageUploaded.read())
Ok, as I'm not saving the image, once I send it to the API the object in itself isn't available anymore.
Not sure to understand why I still can print it, I had to make a copy of it:
if form.is_valid():
imageUploaded = request.FILES['image_file']
imageCopy = copy.deepcopy(imageUploaded)
try:
c = Client(cId, sId)
c.get_token()
tags = c.image_lookup(imageUploaded)
urlImage = base64.b64encode(imageCopy.read())
And now it works perfectly fine!
As asked, here is the code of Image_lookup:
def image_lookup(self, imageUploaded, image_type=None):
'''POST /v1/imageLookup'''
param_files = [
('input_image', ('image.jpg', imageUploaded, image_type or 'image/png'))
]
return self.post('someAPIurl/imageLookup', files=param_files)
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.
Edit: 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()
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')