Pillow: PNG write is failing due to IOError

Created on 20 Aug 2015  路  5Comments  路  Source: python-pillow/Pillow

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?

Most helpful comment

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)

All 5 comments

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)

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.

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.?

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?

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

anonymous530 picture anonymous530  路  3Comments

boskicthebrain picture boskicthebrain  路  4Comments

damianmoore picture damianmoore  路  4Comments

indirectlylit picture indirectlylit  路  4Comments

SysoevDV picture SysoevDV  路  3Comments