-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Closed
Labels
Description
The following code that worked in Pillow 10.4 no longer works with Pillow 11.0.
import pickle
from io import BytesIO
from PIL import Image
im = Image.open("books.jpg")
p = pickle.dumps(im)
im = pickle.loads(p)
# Fails in 11.0, works in 10.4
output = BytesIO()
im.save(output, format=im.format, quality="keep")Error stack.
Traceback (most recent call last):
File "test.py", line 15, in <module>
im.save(output, format=im.format, quality="keep")
File "python3.9/site-packages/PIL/Image.py", line 2605, in save
save_handler(self, fp, filename)
File "python3.9/site-packages/PIL/JpegImagePlugin.py", line 700, in _save
subsampling = get_sampling(im)
File "python3.9/site-packages/PIL/JpegImagePlugin.py", line 643, in get_sampling
if not isinstance(im, JpegImageFile) or im.layers in (1, 4):
File "python3.9/site-packages/PIL/JpegImagePlugin.py", line 396, in __getattr__
raise AttributeError(name)
AttributeError: layersThis has been traced to the following change in src/PIL/JpegImagePlugin.py
Pillow 10.4.0
def get_sampling(im):
...
if not hasattr(im, "layers") or im.layers in (1, 4):
return -1
...Pillow 11.0.0
def get_sampling(im: Image.Image) -> int:
...
if not isinstance(im, JpegImageFile) or im.layers in (1, 4):
return -1
...Suggested fix
def get_sampling(im: Image.Image) -> int:
...
if not isinstance(im, JpegImageFile) or not hasattr(im, "layers") or im.layers in (1, 4):
return -1
...Note that the following hack does workaround the issue in 11.0.
im.layers = 1
im.save(output, format=im.format, quality="keep")