I'm working on a project where I receive a stream of JPEG images over WiFi, convert them to a bytearray, save them as PNG images and read them. The PIL.UnidentifiedImageError occurs when I attempt to open an saved PNG image.
This is how I save the bytearray of JPEG images into PNG images:
idx = random.randint(0,300)
image = Image.open(io.BytesIO(imgdata))
image.save(os.getcwd() + '/Frames/%d.png' % idx)
This is how I open the saved PNG images:
for file in os.listdir('/home/bitcraze/Desktop/AIdeck_examples/NINA/Frames/.'):
print (file)
if file.endswith(".png"):
full_file_path = '/home/Desktop/Frames/' + file
img_file = Image.open(full_file_path)
I checked other posts related to PIL.UnidentifiedImageError and it seems like it could be because the image is corrupted. The picture below shows how I receive the JPEG images:
EDIT: someone suggested I should include how I show the image.
img_loader = GdkPixbuf.PixbufLoader()
img_loader.write(imgdata)
img_loader.close()
pix = img_loader.get_pixbuf()
GLib.idle_add(self._update_image, pix)
The object list_of_contents[0] is based64. I am trying to convert it to it's original image.
image_64_decode = base64.b64decode(list_of_contents[0])
image_result = open('test.jpg', 'wb')
image_result.write(image_64_decode)
img = Image.open(r'C:\Users\st-am\CANCER_APP\test.jpg')
However, I get the following error:
PIL.UnidentifiedImageError: cannot identify image file 'C:\\Users\\st-am\\CANCER_APP\\test.jpg'
Anybody has an idea why PIL cannot identify the image?
Here is the image
Context
I have made a simple web app for uploading content to a blog. The front sends AJAX requests (using FormData) to the backend which is Bottle running on Python 3.7. Text content is saved to a MySQL database and images are saved to a folder on the server. Everything works fine.
Image processing and PIL/Pillow
Now, I want to enable processing of uploaded images to standardise them (I need them all resized and/or cropped to 700x400px).
I was hoping to use Pillow for this. My problem is creating a PIL Image object from the file object in Bottle. I cannot initialise a valid Image object.
Code
# AJAX sends request to this route
#post('/update')
def update():
# Form data
title = request.forms.get("title")
body = request.forms.get("body")
image = request.forms.get("image")
author = request.forms.get("author")
# Image upload
file = request.files.get("file")
if file:
extension = file.filename.split(".")[-1]
if extension not in ('png', 'jpg', 'jpeg'):
return {"result" : 0, "message": "File Format Error"}
save_path = "my/save/path"
file.save(save_path)
The problem
This all works as expected, but I cannot create a valid Image object with pillow for processing. I even tried reloading the saved image using the save path but this did not work either.
Other attempts
The code below did not work. It caused an internal server error, though I am having trouble setting up more detailed Python debugging.
path = save_path + "/" + file.filename
image_data = open(path, "rb")
image = Image.open(image_data)
When logged manually, the path is a valid relative URL ("../domain-folder/images") and I have checked that I am definitely importing PIL (Pillow) correctly using PIL.PILLOW_VERSION.
I tried adapting this answer:
image = Image.frombytes('RGBA', (128,128), image_data, 'raw')
However, I won’t know the size until I have created the Image object. I also tried using io:
image = Image.open(io.BytesIO(image_data))
This did not work either. In each case, it is only the line trying to initialise the Image object that causes problems.
Summary
The Bottle documentation says the uploaded file is a file-like object, but I am not having much success in creating an Image object that I can process.
How should I go about this? I do not have a preference about processing before or after saving. I am comfortable with the processing, it is initialising the Image object that is causing the problem.
Edit - Solution
I got this to work by adapting the answer from eatmeimadanish. I had to use a io.BytesIO object to save the file from Bottle, then load it with Pillow from there. After processing, it could be saved in the usual way.
obj = io.BytesIO()
file.save(obj) # This saves the file retrieved by Bottle to the BytesIO object
path = save_path + "/" + file.filename
# Image processing
im = Image.open(obj) # Reopen the object with PIL
im = im.resize((700,400))
im.save(path, optimize=True)
I found this from the Pillow documentation about a different function that may also be of use.
PIL.Image.frombuffer(mode, size, data, decoder_name='raw', *args)
Note that this function decodes pixel data only, not entire images.
If you have an entire image file in a string, wrap it in a BytesIO object, and use open() to load it.
Use StringIO instead.
From PIL import Image
try:
import cStringIO as StringIO
except ImportError:
import StringIO
s = StringIO.StringIO()
#save your in memory file to this instead of a regular file
file = request.files.get("file")
if file:
extension = file.filename.split(".")[-1]
if extension not in ('png', 'jpg', 'jpeg'):
return {"result" : 0, "message": "File Format Error"}
file.save(s)
im = Image.open(s)
im.resize((700,400))
im.save(s, 'png', optimize=True)
s64 = base64.b64encode(s.getvalue())
From what I understand, you're trying to resize the image after it has been saved locally (note that you could try to do the resize before it is saved). If this is what you want to achieve here, you can open the image directly using Pillow, it does the job for you (you do not have to open(path, "rb"):
image = Image.open(path)
image.resize((700,400)).save(path)
I am a beginner in Python and here is my problem.
I get an image from an url and I want to resize it before saving (copy) it to my server.
Here is my current (not working) code:
urlImage = urllib2.urlopen(URL)
img = Image.open(urlImage)
imgResize = img.resize((weight, height), Image.ANTIALIAS)
os.system("scp -r %s MYSERVER" % (imgResize))
I'm getting this error:
sh: 1: cannot open PIL.Image.Image: No such file
I'm guessing that the problem is that imgResize is not a path (string) but an object and so my os.system call is building up a string that expects a path.
Any solution on how to resolve this problem ?
How can I get a raw file into an Image Object of Pillow python library ?
when i try the following code :
path = '/Users/me/Desktop/SonyRX100III_raw.ARW'
img = Image.open(path)
I get this error
OSError: cannot identify image file '/Users/me/Desktop/SonyRX100III_raw.ARW'