Question

I am developing an addon for Blender 2.69. I am using the Image module of the PIL library in the addon.

According to instructions I found on the internet, I first installed PIL for Python33 and then copied the folder from site-packages of Python into the same folder of Blender.

Functions such as Image.open() work, as do the functions to read the Exif data.

However, the following statement fails, and Blender crashes.

img.save(outputFileName)

The save() method is in the Image.py module of PIL. Here are the relevant parts:

try:
    import builtins
except ImportError:
    import __builtin__
    builtins = __builtin__
...
...
def save(self, fp, format=None, **params):
    ...
    try:
        # Following statement fails, and Blender crashes.
        save_handler(self, fp, filename)
    finally:
        if close:
            fp.close()

This same statement works when executing with the Python 3.3 interpreter (instead of the Blender interpreter). This statement also works in Blender only when the image format is PNG. It fails (in Blender) for all other formats - TIFF, PGM, JPEG, etc.

I did some digging, and a couple of issues were reported on the Pillow github repo recently: (1) (2)

Even more intriguing is this forum post from 2009, which reports exactly identical behavior inside Maya's python interpreter.

I get no stack trace in Blender when this happens, because Blender just crashes. I'd bet it's the same error as the one in the Maya python post.

What might be causing this problem? And is there any solution besides using some other image conversion method?

Was it helpful?

Solution

I still haven't found the exact cause of this problem, but I did manage to find a workaround.

Instead of using img.save() to write to a file directly, write to a buffer. Then write the buffer to a file. This works and does not crash Blender.

So, instead of writing this:

img.save(outputFileName)

Write this:

    from io import BytesIO
    buffer = BytesIO()
    img.save(buffer, format = "jpeg")
    open(outputFileName, "wb").write(buffer.getvalue())

For supported formats, check this link.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top