I'm making a simple API in Flask that accepts an image encoded in base64, then decodes it for further processing using Pillow.
I've looked at some examples (1, 2, 3), and I think I get the gist of the process, but I keep getting an error where Pillow can't read the string I gave it.
Here's what I've got so far:
import cStringIO from PIL import Image import base64 data = request.form image_string = cStringIO.StringIO(base64.b64decode(data['img'])) image = Image.open(image_string)
which gives the error:
IOError: cannot identify image file <cStringIO.StringIO object at 0x10f84c7a0>
To decode a file with contents that are base64 encoded, you simply provide the path of the file with the --decode flag. As with encoding files, the output will be a very long string of the original file. You may want to output stdout directly to a file.
Base64 is an encoding, the strings you've posted are encoded. You can DECODE the base64 values into bytes (so just a sequence of bits). And from there, you need to know what these bytes represent and what original encoding they were represented in, if you wish to convert them again to a legible format.
To decode an image using Python, we simply use the base64. b64decode(s) function. Python mentions the following regarding this function: Decode the Base64 encoded bytes-like object or ASCII string s and return the decoded bytes.
Q Why does an = get appended at the end? A: As a short answer: The last character ( = sign) is added only as a complement (padding) in the final process of encoding a message with a special number of characters.
You should try something like:
from PIL import Image from io import BytesIO import base64 data['img'] = '''R0lGODlhDwAPAKECAAAAzMzM/////wAAACwAAAAADwAPAAACIISPeQHsrZ5ModrLl N48CXF8m2iQ3YmmKqVlRtW4MLwWACH+H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw==''' im = Image.open(BytesIO(base64.b64decode(data['img'])))
Your data['img']
string should not include the HTML tags or the parameters data:image/jpeg;base64
that are in the example JSFiddle.
I've changed the image string for an example I took from Google just for readability purposes.
There is a metadata prefix of data:image/jpeg;base64,
being included in the img
field. Normally this metadata is used in a CSS or HTML data URI when embedding image data into the document or stylesheet. It is there to provide the MIME type and encoding of the embedded data to the rendering browser.
You can strip off the prefix before the base64 decode and this should result in valid image data that PIL can load (see below), but you really need to question how the metadata is being submitted to your server as normally it should not.
import re import cStringIO from PIL import Image image_data = re.sub('^data:image/.+;base64,', '', data['img']).decode('base64') image = Image.open(cStringIO.StringIO(image_data))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With