Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PNG write is failing due to IOError #1380

Closed
bschollnick opened this issue Aug 20, 2015 · 6 comments
Closed

PNG write is failing due to IOError #1380

bschollnick opened this issue Aug 20, 2015 · 6 comments

Comments

@bschollnick
Copy link

Folks,

I believe I have found an file (JPG) that is causing PIL to report a false IO Error, and write a zero byte file.

Now the following code is working fine for other JPG, PNG, etc files:

(Please excuse the try / except block, I've been trying to debug this)

        try:
            image_file = Image.open(src_filename)
        except IOError:
            print "File thumbnail ", src_filename
            print "save thumbnail ", t_filename
            print "IOError opening the file[%s] ." % (src_filename)
        except IndexError as detail:
            print "File thumbnail ", src_filename
            print "save thumbnail ", t_filename
            print "The File [%s] generated an IndexError." % (src_filename)
            print detail
        except TypeError:
            print "File thumbnail ", src_filename
            print "save thumbnail ", t_filename
            print "The File [%s] is not the proper type (TypeError)." % (src_filename)

            image_file.thumbnail((t_size, t_size), Image.ANTIALIAS)

        try:
            image_file.save(t_filename, "PNG", optimize=True)
            return True
        except IOError:
            print "File thumbnail ", src_filename
            print "save thumbnail ", t_filename
            print "IOError writing the file[%s] ." % (src_filename)
        except IndexError as detail:
            print "File thumbnail ", src_filename
            print "save thumbnail ", t_filename
            print "The File [%s] (IndexError) is damaged." % (src_filename)
            print detail
        except TypeError:
            print "File thumbnail ", src_filename
            print "save thumbnail ", t_filename
            print "The File [%s] (TypeError) is damaged." % (src_filename)

The JPG in question is a straight forward JPG, and is available from, https://dl.dropboxusercontent.com/u/241415/pil/Bubblegum_Crisis.jpg.

Yes, the code is taking an image file (in this case JPG), resizing it, and then saving it as a PNG. It's creating thumbnails for an image gallery. The code has been working fine, and is still working fine for the majority of the files. It's a small number of files, that seem to be causing a problem. As far as I can tell, it's internal to Pil.

I've tried with and without compression being turned on.

I've tried resaving the file in JPG form, with no change. Saving it as a PNG file, resolves the issue, but doesn't solve the underlying issue.

Does anyone have a suggestion on how to solve the problem? What is it in the file that is causing the IOError when writing to disk?

Is there any recommendations on what to debug on the PIL side?

@radarhere
Copy link
Member

If you remove the try blocks, you will see that the error being generated is IOError: cannot write mode CMYK as PNG. If you search around on Google, you will find that PNG images do not support CMYK mode. So the reason you've having this issue with just this file, rather than others, is that this image file is in a different mode.

To workaround this, simply convert the image to a different mode before saving - for example, image_file.convert('RGB').save(t_filename, "PNG", optimize=True)

@bschollnick
Copy link
Author

Thank you! Thank you for the fast response, too.

That makes sense. But what confused me was that this is being returned as an IO Error?
Wouldn't it be more obvious with a Invalid Image Data error? Or something like that?

I was capturing IOError, due to bad paths, etc. I never though that IOError would be triggered due to image data / conversion issues.

@vashek
Copy link
Contributor

vashek commented Aug 20, 2015

Also, wouldn't it be nice to have a generic method that makes sure the image is saveable in the given format, without needing to know which formats support CMYK, transparency, floating-point pixels etc.?

@bschollnick
Copy link
Author

Yes, exactly!

I wasn't thinking along those lines, but for example:

image_file = Image.open(src_filename)
image_file.thumbnail((t_size, t_size), Image.ANTIALIAS)
image_file.ensure_valid_options("PNG", fix_issues=True)
image_file.save(t_filename, "PNG", optimize=True)

Where the first option is the File Format to check for (e.g. Saved format), and the next is a boolean that controls if it fails, or if it enforces the valid options. For example, with PNG, ensuring that it is RGB.

Or possibly roll something like this into Image.Save, as option. Default it to OFF to preserve previous behavior.

Is there a reference that would give me what file formats, require what features?

@wiredfool
Copy link
Member

Sadly, there is no complete reference other than the code. We're working on improving the documentation, but it's a long slow process.

@kawache
Copy link

kawache commented Jan 20, 2022

if image_file.mode == "CMYK":
    image_file = image_file.convert("RGB")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants