anibali / pywebp

Python bindings for WebP
MIT License
74 stars 24 forks source link

ValueError: not enough values to unpack (expected 3, got 2) On some images #13

Closed noisytoken closed 5 years ago

noisytoken commented 5 years ago

The save_image() raises ValueError on some images. Here is the image and code to reproduce the error.

from PIL import Image
import webp

img = Image.open('/home/x/Pictures/img1.png')
webp.save_image(img, '/home/x/Pictures/img2.webp', quality=80)

img1

Stack trace:

/home/x/my_project/env/bin/python /home/x/my_project/django_project/wiki/tmp.py
Traceback (most recent call last):
  File "/home/x/my_project/django_project/wiki/tmp.py", line 5, in <module>
    webp.save_image(img, '/home/x/my_project/django_project/media/tmp/error.webp', quality=80)
  File "/home/x/my_project/env/lib/python3.6/site-packages/webp/__init__.py", line 557, in save_image
    imwrite(file_path, np.asarray(img), pilmode=img.mode, **kwargs)
  File "/home/x/my_project/env/lib/python3.6/site-packages/webp/__init__.py", line 444, in imwrite
    pic = WebPPicture.from_numpy(arr, pilmode=pilmode)
  File "/home/x/my_project/env/lib/python3.6/site-packages/webp/__init__.py", line 202, in from_numpy
    ptr.height, ptr.width, bytes_per_pixel = arr.shape
ValueError: not enough values to unpack (expected 3, got 2)
anibali commented 5 years ago

The error message is bad, and I'll fix that. However, for your use case the problem is that the image is greyscale, which is not a valid image input mode for libwebp. To get around this, add the following line after loading the image:

img = img.convert('RGB')
anibali commented 5 years ago

Fixed error message in https://github.com/anibali/pywebp/commit/98b1afab7da6740eb223bebbb31ea6d52761a6af

noisytoken commented 5 years ago

I am mostly dealing with png images and on occasions, cwebp dramatically increases the file size. How to optimize such images?

anibali commented 5 years ago

Not sure. Could it be that those images are the greyscale ones? As far as I know, webp does not have a greyscale profile so they would be stored as RGB images, which could result in larger files.