Question

I've been using sorl-thumbnail for some time without problems. However, the following error started to appear: encoder error -2 when writing image file.

The following code causes the error:

from sorl.thumbnail import get_thumbnail
photobooth_thumbnail = get_thumbnail(img_file,
    PHOTOBOOTH_THUMB_SIZE, crop='center', quality=99)

being img_file a Django models' ImageField and when PHOTOBOOTH_THUMB_SIZE is "sufficiently large". When I was using PHOTOBOOTH_THUMB_SIZE = '670', everything worked just fine, but when I increased it to PHOTOBOOTH_THUMB_SIZE = '1280', the aforementioned error appeared.

I'm suspecting this is an error in PIL rather than in sorl-thumbnail, given the low level message. I'd like to have bigger thumbnails, so I'd appreciate any help on this. Thanks in advance.

Was it helpful?

Solution

I ended up patching the file pil_engine.py in /lib/python2.7/site-packages/sorl/thumbnail/engines:

--- pil_engine.py   2013-09-09 03:58:27.000000000 +0000
+++ pil_engine_new.py   2013-11-05 21:19:15.053034383 +0000
@@ -79,6 +79,7 @@
             image.save(buf, **params)
         except IOError:
             params.pop('optimize')
+            ImageFile.MAXBLOCK = image.size[0] * image.size[1]
             image.save(buf, **params)
         raw_data = buf.getvalue()
         buf.close()

This fixed the issue for me.

OTHER TIPS

Looks like this error only happens for some images on some settings. So if you change at least one param for image.save(), as @Pablo Antonio noted. I might work. I do the following:

def img_save(img):
    quality = 80  # Default level we start from and decrease till 30
    need_retry = True
    while need_retry:
        try:
            img.save(self.dst_image_file, 'JPEG', quality=quality, optimize=True, progressive=True)
        except IOError as err:
            quality = quality - 1
            if quality <= 20:
                need_retry = False
        else:
            need_retry = False

I solved this problem with the help of thumbnail quality modification according to the size of the image.

def thumbnail_quality_calc(size, max_block=720*720):
    q_ratio = size / max_block
    # can also include the PHOTOBOOTH_THUMB_SIZE in the logic to calculate the q_ratio to improve the formula
    return math.floor(100 - q_ratio)

from sorl.thumbnail import get_thumbnail
img_quality = thumbnail_quality_calc(size=img_file.size)
photobooth_thumbnail = get_thumbnail(img_file,PHOTOBOOTH_THUMB_SIZE, crop='center', quality=img_quality)

# example
# size = 1024*1024
# quality will be 97
# This will help you to prevent encoder error

The error is caused if the size of the image is too huge and you want its thumbnail which is cropped but with high quality, either you increase MAX block size or you decrease the quality. The above solution uses the second method, helps you without changing the base package code.

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