OSError: cannot identify image file (issue with certain images) - python

I have a script that is downloading and performing certain operations on files from a website. A couple of times a week some of the images will throw this error (edit for bump):
OSError: cannot identify image file '57343948435235236aede7dceb672559.png'
Even when manually running code as simple as the following, it produces the error:
imagefile = Image.open('57343948435235236aede7dceb672559.png')
Here are the important facts:
If I redownload the file using requests.get() I get the same error when attempting to open it.
If I redownload the file by saving it using a web browser, I instead get the error PIL.UnidentifiedImageError: cannot identify image file when attempting to open it using PIL
I can view the files (using Window Photo Viewer, a Linux image viewer, etc.) so they aren't completely corrupted.
If I open the image in Paint and save it under the same name, I can then open it using PIL.
Given all this, it appears to be an issue with specific image files hosted on the site; they are viewable in applications, but not openable using PIL. I'm assuming something is wrong with the byte structure or headers in the image, and saving overwrites those issues. Is there some library or automatic process I can use to 'fix' these images when the error occurs?
Below, I am including a minimal, reproducible example. PLEASE NOTE: THE EXAMPLE URL IN THIS CASE IS NSFW IN NATURE, AND THEREFORE HAS BEEN REDACTED. SEE MY COMMENT TO THIS POST FOR A PASTEBIN LINK TO THE FULL CODE.
from PIL import Image
url = 'SEE ABOVE NOTE'
file_name =(url).split('/')[-1:][0]
# Downloading the image file data.
file_data = get(url).content
# Write the data to a file.
with open(file_name, 'wb+') as file_object:
file_object.write(file_data)
# Opening the image with PIL
with Image.open(file_name) as image_file:
# "OSError: cannot identify image file" happens here
pass

Related

Open JPEG file with PIL and OpenCV fails

I have lots of images saved with no file extension.
I am trying to convert those images and do some work with PIL:
for img_path in list_imgs:
with Image.open(img_path) as img:
# more code
For some files this works ok but for others it shows PIL.UnidentifiedImageError. I tried to handle the exception by opening the file with OpenCV:
img = cv2.imread(img_path)
But I get the following error:
[ WARN:0#2.312] global D:\a\opencv-python\opencv-python\opencv\modules\imgcodecs\src\grfmt_tiff.cpp (462) cv::TiffDecoder::readData OpenCV TIFF: TIFFRGBAImageOK: Sorry, requested compression method is not configured
If I manually changed the file extension to .jpg for the specific file that files, I can open it using Windows Photos or any other app, even Microsoft Paint, so I know that the file is not damaged. However, both OpenCV and PIL have problems reading said file.
How can I open the image? Are there any other parameters that can be configured? Or can it be read directly into a NumPy array and then handled to PIL?

Discord.Py blend pictures and send them without dowload them

I have the following problem:
1.- I want to send a file in discord without dowloading. I don't know if this is posible but I want to send it for example with BytesIo.
2.- I have one picture saved on my Bot files and the other one comes from ctx.author.avatar
3.- I want to blend both images and send the result. With blend I mean like for example if I would be using cv2 I would use addWeighted().
The Code I have right know what does is dowload the picture of the member, using cv2 to read both pictures, resize them and use addWeighted. After that I save the blend picture and I send it as a message. When all It's done I delete the pictures (both, the avatar and the blend one). From my point of view this is really inefficient, thats why I want know if there is a way using PIL and BytesIo or something to use the dataArray to blend them and send it without dowload it.
So in short, I want to know if there is a way to blends both images without download the second one (member avatar picture) and send it without dowloading the blend image.
I can the code I already have if needed but as my code is download the picture I guess that won't help.
You can get the image's URL from the message (Get a picture from the message):
message.attachments[0].url
Then load the image into memory with the requests library (How to open an image from an url with opencv using requests from python)
The way I found at the end to solve it, was using just Pillow doing the following:
image1 = Image.open("img.jpg", mode='r')
image2 = Image.open(requests.get(url, stream=True).raw)
With I have both images on memory, so I just needed to resize both of them and blend. Finally I just used io.Bytes() to make into bytes and send it.
How to blend -> https://pythontic.com/image-processing/pillow/blend

Downloading an image in Python does not properly display it

I am using PyCharm in order to download an image from a fixed URL
This is the code I'm using in order to do it:
import urllib.request
import random
def download_web_image(url):
name=random.randrange(0,1000)
fullname=str(name)+".jpg"
urllib.request.urlretrieve(url,fullname)
download_web_image('imagizer.imageshack.com/v2/626x626q90/673/MT82dR.jpg')
This is what happens when I double click the downloaded image:
But as you see the image is already downloaded in the Python directory and it is a proper image:
What do I have to do in order for the image to be properly displayed in Pycharm?
This has nothing to do with the fact that the image was downloaded using Python. You will see the same behaviour if you copy an image into your project folder. You can fix it by telling PyCharm about which file types should be displayed as images.
In Settings (File->Settings on Windows) expand Editor then select File Types
Choose Image from the list of Regognized File Types (scroll down...) then make sure that Registered Patterns contains all the file types you want to be displayed as images. If *.jpg is not listed there, add it using the green + on the right.

Can't save Matplotlib images to a readable .tif format

I'm having trouble saving my Matplotlib plots to a readable .tiff format. The file itself does save, but when I double-click on it on the folder, I get the following error in Windows Photo Viewer:
"Windows Photo Viewer can't open this picture because either Photo Viewer doesn't support this file format, or you don't have the latest updates to Photo Viewer."
But attempted workarounds such as trying to load the file with Paint or Photo do not work. I get the feeling that the file is not saving correctly. (The image displays just fine and can be saved as a .gif just fine.) How do I resolve this?

Downloading a section of an Image from a website in python?

I am currently able to download an entire image from a URL using
from PIL import Image, ImageTk
import cStringIO
import urllib
url = http://prestigemgmt.us/wp-content/uploads/2013/03/dog.jpg
self.image = Image.open(cStringIO.StringIO(urllib.urlopen(url).read()))
It works fine and gets the whole image from the website. My question is there any way to get, lets say only the right half of the image.
I understand I could edit the image after it is downloaded, but speed is an important aspect, so ideally I would download only what I need.
It is not possible to do this.
The common image file formats like PNG and JPEG are encoded in a manner that you cannot download an arbitrary part of the picture without downloading the full picture.
You need to download the whole picture, decode it and edit it after the download.
For the advanced knowledge you can always study PNG and JPEG file formats.
If you are in the control of the server providing the images you can write a server-side script which edits the image on the server and then sends the edit over the wire.

Categories