I have a byte string, and trying to convert it into a file but I keep getting an error:
OS Error cannot identify image file <_io.BytesIO object at 0x03BBD330>
The code that I've implemented is below:
def test_view(request):
with open("test_json.json") as imageFile:
b=bytearray(json.load(imageFile)["IMAGE_DATA"], 'utf8')
print(b)
image = Image.open(io.BytesIO(b))
response = HttpResponse(content_type="image/jpeg")
image.save(response, "JPEG")
return response
The byte string is read from a json file, it looks like this, but it is much longer, I've just copied some characters.
"b'\\xff\\xd8\\xff\\xe0\\x00\\x10JFIF\\x00\\x01\\x01\\x01\\x00`\\x00`\\x00\\x00\\xff\\xdb\\x00C\\x00\\x05\\x04\\x04\\x04\\x04\\x03\\x05\\x04\\x04\\x04\\x06\\x05\\x05\\x06\\x08\\r\\x08\\x08\\x07\\x07\\x08\\x10\\x0b\\x0c\\t\\r\\x13\\x10\\x14\\x13\\x12\\x10\\x12\\x12\\x14\\x17\\x1d\\x19\\x14\\x16\\x1c\\x16\\x12\\x12\\x1a#\\x1a\\x1c\\x1e\\x1f!!!\\x14\\x19$\\'$ &\\x1d ! \\xff\\xdb\\x00C\\x01\\x05\\x06\\x06\\x08\\x07\\x08\\x0f\\x08\\x08\\x0f \\x15\\x12\\x15 \\xff\\xc0\\x00\\x11\\x08\\x01&\\x02q\\x03\\x01\"\\x00\\x02\\x11\\x01\\x03\\x11\\x01\\xff\\xc4\\x00\\x1f\\x00\\x00\\x01\\x05\\x01\\x01\\x01\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\xff\\xc4\\x00\\xb5\\x10\\x00\\x02\\x01\\x03\\x03\\x02\\x04\\x03\\x05\\x05\\x04\\x04\\x00\\x00\\x01}\\x01\\x02\\x03\\x00\\x04\\x11\\x05\\x12!1A\\x06\\x13Qa\\x07\"q\\x142\\x81\\x91\\xa1\\x08#B\\xb1\\xc1\\x15R\\xd1\\xf0$3br\\x82\\t\\n\\x16\\x17\\x18\\x19\\x1a%&\\'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9\\xaa\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7\\xb8\\xb9\\xba\\xc2\\xc3\\xc4\\xc5\\xc6\\xc7\\xc8\\xc9\\xca\\xd2\\xd3\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xe1\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xff\\xc4\\x00\\x1f\\x01\\x00\\x03\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\xff\\xc4\\x00\\xb5\\x11\\x00\\x02\\x01\\x02\\x04\\x04\\x03\\x04\\x07\\x05\\x04\\x04\\x00\\x01\\x02w\\x00\\x01\\x02\\x03\\x11\\x04\\x05!1\\x06\\x12AQ\\x07aq\\x13\"2\\x81\\x08\\x14B\\x91\\xa1\\xb1\\xc1\\t#3R\\xf0\\x15br\\xd1\\n\\x16$4\\xe1%\\xf1\\x17\\x18\\x19\\x1a&\\'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99'"
I am not entirely sure what exactly is the best solution to this issue because the problem you're running into is that json.load(imageFile)["IMAGE_DATA"] is going to return "b'bytes'", which when it converts to bytearray, you're doing bytearray("b\'bytes\'"), which is wrong.
Also this behavior is specific between JSON parsers, and different JSON parsers might interpret differently
Either strip the b'' that's wrapping your bytestring, or do an ast.literal_eval()
def test_view(request):
with open("test_json.json") as imageFile:
b = bytearray(
ast.literal_eval(
json.load(imageFile)["IMAGE_DATA"], 'utf8')
print(b)
image = Image.open(io.BytesIO(b))
response = HttpResponse(content_type="image/jpeg")
image.save(response, "JPEG")
return response
Related
I have a jpg image that is in memory and therefore is in bytes. I then compress it with the following:
zlib.compress(pickle.dumps(self.fileInstance))
I compress it to store it into a MongoDB database. This image is one of the elements in the record that I save. I save the with the following.
list_search_result = list(search_result)
json_search_result = json.dumps(list_search_result, cls=Encoder, indent=2)
I got an error with bytes and Json, so I simply convert the bytes image to a string with the following.
from bson.objectid import ObjectId
import json
import datetime
class Encoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, ObjectId):
return str(obj)
elif isinstance(obj, datetime.datetime):
return str(obj)
elif isinstance(obj,bytes):
return str(obj)
return super(Encoder, self).default(obj)
Now, I want to recover the image from the json file. I thought that doing the same steps in the opposite order would work but no.
So here is what I do to store:
image -> pickle -> compress -> str -> json
I thought this would work:
json -> bytes -> decompress -> depickle -> image
I receive the zlib.error : Error -3 during the following:
image = pickle.load(zlib.decompress(attachment[1].encode()))
image = io.BytesIO(image)
dt = Image.open(image)
EDIT:
Okay so I was toying around, and I think the issue might be the .encode(). I start with b" ". After str(b" "), I get "b' '". If I do the .encode(), I get b"b' '". How do I deal with this?
str() is useful to display something - it creates text readable for human.
It may show that you had bytes ("b''") or it may show string like \xe0 for values which can't be converted to chars. But it doesn't have to create text useful for keeping in database.
Many databases have field to keep bytes and then you could keep image as bytes (without converting to pickle which may only add more bytes, and without compressing because images already use some compression)
If you have to keep (or send by internet) file as string then better convert it to base64. And this method used by some APIs to send image in JSON.
Convert image to base64
import base64
fh = open('lenna.png', 'rb')
data = fh.read()
fh.close()
data = base64.b64encode(data).decode()
print(text[:100]) # text
# ... save in database ...
Convert base64 to image
# ... read from database ...
data = base64.b64decode(text.encode())
print(data[:100]) # bytes
fh = open('lenna.png', 'wb')
fh.write(data)
fh.close()
Result:
# text
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAIAAAB7GkOtAAAAA3NCSVQICAjb4U/gAAAgAElEQVR4nOzbXa5tS5Il5DHMzH3OtfY+
# bytes
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x02\x00\x00\x00\x02\x00\x08\x02\x00\x00\x00{\x1aC\xad\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00 \x00IDATx\x9c\xec\xdb]\xaemK\x92%\xe41\xcc\xcc}\xce\xb5\xf6>\xe7\xde\x88\xc8\xa2\x1e\xea\x85\x16 !$\x10\x88?\x05/t\x06\x95\xc8\xe2\x95\x06\xd0'
Tested on image lenna.png (Wikipedia: Lenna)
My Flask app is receives base64 encoded images like so
`b'"{\\"image\\": \\"/9j/4AAQSkZJRgABAQEASABIAAD/4gxYSUNDX1BST0ZJTEUAAQEAAAxITGlubwIQAABtbnRyU...opHNf//Z\\", \\"id\\": \\"e3ad9809-b84c-57f1-bd03-a54e25c59bcc\\"}"'
I have tried a number of ways but I cannot seem to get the image bytes for decoding. If I json.loads this it becomes a string. If I treat it as a bytes dictionary it doesn't take the key and asks it to be an integer which will not work of course. I have tried many things, this is just one other which doesn't work. Any help is appreciated, Thanks.
def main():
try:
p = randint(100, 200)
image = request.data
jsonResponse = json.loads(image.decode('utf-8'))
im = base64.decode(jsonResponse)
print(im)
with open(f'Image{p}.jpg', 'wb') as f:
f.write(im)
If you use request context (from flask import request), then you can access the sended data as a python dictionary using the request.json attribute instead of the request.data.
To get the dictionary as you wish from the example you provided, a double call to json.loads solved the problem:
import json
data = b'"{\\"image\\": \\"/9j/4AAQSkZJRgABAQEASABIAAD/4gxYSUNDX1BST0ZJTEUAAQEAAAxITGlubwIQAABtbnRyU...opHNf//Z\\", \\"id\\": \\"e3ad9809-b84c-57f1-bd03-a54e25c59bcc\\"}"'
data_as_dictionary = json.loads(json.loads(data))
It seems like because your data has the leading " and the trailing ", json.loads is parsing it as a string (which is a valid json) and that's why you don't get the dictionary you want in the first call to json.loads.
import json
import base64
from codecs import encode
request = b'"{\\"image\\": \\"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\\", \\"id\\": \\"e3ad9809-b84c-57f1-bd03-a54e25c59bcc\\"}"'
data_as_dictionary = json.loads(json.loads(request.decode('utf-8')))
base64_img = data_as_dictionary['image']
bytes_img = encode(base64_img, 'utf-8')
binary_img = base64.decodebytes(bytes_img)
with open("imageToSave.jpg", "wb") as fh:
fh.write(binary_img)
you need several steps. first of all, you should transform request data into a python dictionary then take the image as base64 then encode it in bytes array then as binary, and last save it.
The above code works well.
I have a flask get request like this
content = {"vname":"","myPhoto":{"fieldname":"myPhoto","originalname":"flower-purple-lical-blosso.jpg","encoding":"7bit","mimetype":"image/jpeg","buffer":{"type":"Buffer","data":[255,216,255,224,0,...]}
My image file is with the key data.
data = content['myphoto']['buffer']['data']
I am unable to save it as a jpeg file.
I am not sure how to decode this object as an image as its currently a list.
If I correctly understood your question, it could be done like this:
#!/usr/bin/env python3
content = {"vname":"","myPhoto":{"fieldname":"myPhoto","originalname":"flower-purple-lical-blosso.jpg","encoding":"7bit","mimetype":"image/jpeg","buffer":{"type":"Buffer","data":[255,216,255,224,0,20]}}}
data = content['myPhoto']['buffer']['data']
str_data = ''.join(chr(d) for d in data) # build string using list comprehension
bytes_data = str_data.encode() # build bytes array from string
with open('output.jpg', 'wb') as f: # open file for writing bytes
f.write(bytes_data) # write bytes array to file
Code of course is not perfect and could be used as starting point.
I have a base64 string that I've acquired from KineticJS toDataURL(). It's a valid base64 string. This fiddle shows that it is: http://jsfiddle.net/FakRe/
My Problem: I'm sending this dataURI up to my server, decoding using python, and saving on the server. However, I'm getting a padding error. Here's my code:
def base64_to_file(self, image_data, image_name):
extension = re.search('data\:image\/(\w+)\;', image_data)
if extension:
ext = extension.group(1)
image_name = '{0}.{1}'.format(image_name, ext)
else:
# it's not in a format we understand
return None
image_data = image_data + '=' #fix incorrect padding
image_path = os.path.join('/my/image/path/', image_name)
image_file = open(image_path, 'w+')
image_file.write(image_data.decode('base64'))
image_file.close()
return image_file
I can get around this padding error by doing this at the top of my function:
image_data = image_data + '=' #fixes incorrect padding
After I add the arbitrary padding, it decodes successfully and writes to the filesystem. However, whenever I try and view the image, it doesn't render, and gives me the 'broken image' icon. No 404, just a broken image. What gives? Any help would be greatly appreciated. I've already spent way too much time on this as it is.
Steps to recreate (May be pedantic but I'll try and help)
Grab the base64 string from the JSFiddle
Save it to a text file
Open up the file in python, read in the data, save to variable
Change '/path/to/my/image' in the function to anywhere on your machine
Pass in your encoded text variable into the function with an name
See the output
Again, any help would be awesome. Thanks.
If you need to add padding, you have the wrong string. Do make sure you are parsing the data URI correctly; the data:image/png;base64, section is metadata about the encoded value, only the part after the comma is the actual Base64 value.
The actual data portion is 223548 characters long:
>>> len(image_data)
223548
>>> import hashlib
>>> hashlib.md5(image_data).hexdigest()
'03918c3508fef1286af8784dc65f23ff'
If your URI still includes the data: prefix, do parse that out:
from urllib import unquote
if image_data.startswith('data:'):
params, data = image_data.split(',', 1)
params = params[5:] or 'text/plain;charset=US-ASCII'
params = params.split(';')
if not '=' in params[0] and '/' in params[0]:
mimetype = params.pop(0)
else:
mimetype = 'text/plain'
if 'base64' in params:
# handle base64 parameters first
data = data.decode('base64')
for param in params:
if param.startswith('charset='):
# handle characterset parameter
data = unquote(data).decode(param.split('=', 1)[-1])
This then lets you make some more informed decisions about what extension to use for image URLs, for example, as you now have the mimetype parsed out as well.
I want to base-64 encode a PNG file, to include it in a data:url in my stylesheet. How can I do that?
I’m on a Mac, so something on the Unix command line would work great. A Python-based solution would also be grand.
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=='
import base64
def image_to_data_url(filename):
ext = filename.split('.')[-1]
prefix = f'data:image/{ext};base64,'
with open(filename, 'rb') as f:
img = f.read()
return prefix + base64.b64encode(img).decode('utf-8')
This should do it in Unix:
b64encode filename.png X | sed '1d;$d' | tr -d '\n' > b64encoded.png
The encoded image produced by b64encode includes a header and footer and no line longer than 76 characters. This format is typical in SMTP communications.
To make the encoded image embeddable in HTML/CSS, the sed and tr commands remove the header/footer (first & last lines) and all newlines, respectively.
Then just simply use the long encoded string in HTML
<img src="data:image/png;base64,ENCODED_PNG">
or in CSS
url(data:image/png;base64,ENCODED_PNG)
b64encode is not installed by default in some distros (#Clint Pachl's answer), but python is.
So, just use:
python -mbase64 image.jpeg | tr -d '\n' > b64encoded.txt
In order to get base64 encoded image from the command line.
The remaining steps were already answered by #Clint Pachl (https://stackoverflow.com/a/20467682/1522342)
This should work in Python3:
from io import BytesIO
import requests, base64
def encode_image(image_url):
buffered = BytesIO(requests.get(image_url).content)
image_base64 = base64.b64encode(buffered.getvalue())
return b'data:image/png;base64,'+image_base64
Call decode to get str as in python3 base64.b64encode returns a bytes instance.
And just for the record, if you want to do it in Node.js instead:
const fs = require('fs');
const base64encodedString = fs.readFileSync('image_file.jpg', {encoding:'base64'});