27

I'm trying to save with the following call and it raises error, but if i remove progressive and optimize options, it saves.

Here is my test.py that doesn't work:

import Image
img = Image.open("in.jpg")
img.save("out.jpg", "JPEG", quality=80, optimize=True, progressive=True)

It raises this error:

Suspension not allowed here
Traceback (most recent call last):
  File "test.py", line 3, in <module>
    img.save("out.jpg", "JPEG", quality=80, optimize=True, progressive=True)
  File "/Library/Python/2.6/site-packages/PIL/Image.py", line 1439, in save
    save_handler(self, fp, filename)
  File "/Library/Python/2.6/site-packages/PIL/JpegImagePlugin.py", line 471, in _save
    ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)])
  File "/Library/Python/2.6/site-packages/PIL/ImageFile.py", line 501, in _save
    raise IOError("encoder error %d when writing image file" % s)
IOError: encoder error -2 when writing image file

Link to image: http://static.cafe.nov.ru/in.jpg (4.3 mb)

Andrey Kuzmin
  • 4,479
  • 2
  • 23
  • 28
  • I copied and pasted that line and tested it with a random image, and it worked fine. Please add more code and maybe link to a sample image / data that causes the problem so that it's reproduceable – agf Jul 22 '11 at 10:31
  • agf, I updated the question with all details. I've got an idea, that maybe it doesn't work because of the big size of image. I tested with the smaller one, and it worked. I still need to know the limits of when I can use progressive setting. – Andrey Kuzmin Jul 22 '11 at 10:58
  • related: [Automatic scaling of Image.MAXBLOCK](https://github.com/python-imaging/Pillow/issues/148) – jfs Dec 26 '13 at 13:20

3 Answers3

41
import PIL
from exceptions import IOError

img = PIL.Image.open("c:\\users\\adam\\pictures\\in.jpg")
destination = "c:\\users\\adam\\pictures\\test.jpeg"
try:
    img.save(destination, "JPEG", quality=80, optimize=True, progressive=True)
except IOError:
    PIL.ImageFile.MAXBLOCK = img.size[0] * img.size[1]
    img.save(destination, "JPEG", quality=80, optimize=True, progressive=True)

PIL encodes part of the image at a time. This is incompatible with the 'optimize' and 'progressive' options.

Edit: You need to import PIL.Image, PIL.ImageFile for newer versions of PIL / Pillow.

agf
  • 171,228
  • 44
  • 289
  • 238
  • You now have to say `from PIL import ImageFile` and `ImageFile.MAXBLOCK = img.size[0] * img.size[1] * 4`. I think you do need 4x the image size, or maybe only 3x, for rgb. Anyway it still failed for me without that. – GaryO Jul 26 '13 at 02:49
  • @GaryO Why would you need to do 4x the image size? Are you saying the block is measured in bytes, and you're assuming 4 bytes per pixel? I don't think you need to adjust for that, plus that size would be wrong for a jpeg, since it's compressed. – agf Jul 26 '13 at 04:23
  • Well, actually the 4x didn't even work for me. I still get IOError. So you might be right. I assumed `MAXBLOCK` (aka bufsize) was for holding raw image pixels, not compressed bytes, since the code normally sets it to `img.size[0] * 4` but I don't really understand the code. – GaryO Jul 26 '13 at 20:51
27

Here's a hack that might work, but you may need to make the buffer even larger:

from PIL import Image, ImageFile

ImageFile.MAXBLOCK = 2**20

img = Image.open("in.jpg")
img.save("out.jpg", "JPEG", quality=80, optimize=True, progressive=True)
Eryk Sun
  • 33,190
  • 5
  • 92
  • 111
4

If you have installed PIL using pip, uninstall it and instal pillow. The pillow library has the edge version of PIL library with it. The PIL from pip is too old. If you update to pillow instead of PIL, you don't have to set PIL.ImageFile.MAXBLOCK. It is taken care of automatically.

If you used git submodule of just have PIL source code downloaded in to repo, make sure you download the latest source from GitHub and use it.

dhilipsiva
  • 3,688
  • 1
  • 24
  • 35