Repository: python-pillow/Pillow

Issue:
How to save WebP?
<!--
Thank you for reporting an issue.

Follow these guidelines to ensure your issue is handled properly.

If you have a ...

1.  General question: consider asking the question on Stack Overflow
    with the python-imaging-library tag:

    * https://stackoverflow.com/questions/tagged/python-imaging-library

    Do not ask a question in both places.

    If you think you have found a bug or have an unexplained exception
    then file a bug report here.

2.  Bug report: include a self-contained, copy-pastable example that
    generates the issue if possible. Be concise with code posted.
    Guidelines on how to provide a good bug report:

    * https://stackoverflow.com/help/mcve

    Bug reports which follow these guidelines are easier to diagnose,
    and are often handled much more quickly.

3.  Feature request: do a quick search of existing issues
    to make sure this has not been asked before.

We know asking good questions takes effort, and we appreciate your time.
Thank you.
-->

### What did you do?
Trying to save the image

### What did you expect to happen?
Saving image in webp format

### What actually happened?
Error
### What are your OS, Python and Pillow versions?

* OS: linux (debian) with libwebp 0.5.2-1+deb9u1 and macos bigsur 
* Python: 3.8.8 and 3.9.6
* Pillow: 8.3.1

When I try to save the image (jpg) - I get the error:

```python
    img.save(fp, format, **save_options)
  File "[...]/.venv/lib/python3.8/site-packages/PIL/Image.py", line 2235, in save
    save_handler(self, fp, filename)
  File "[...]/.venv/lib/python3.8/site-packages/PIL/WebPImagePlugin.py", line 327, in _save
    data = _webp.WebPEncode(
TypeError: a bytes-like object is required, not 'NoneType'
```

```python
# with `save_options['save_all'] = True` :
    img.save(fp, format, **save_options)
  File "[...]/.venv/lib/python3.9/site-packages/PIL/Image.py", line 2236, in save
    save_handler(self, fp, filename)
  File "[...]/.venv/lib/python3.9/site-packages/PIL/WebPImagePlugin.py", line 179, in _save_all
    _save(im, fp, filename)
  File "[...]/.venv/lib/python3.9/site-packages/PIL/WebPImagePlugin.py", line 328, in _save
    data = _webp.WebPEncode(
TypeError: a bytes-like object is required, not 'NoneType'
```



Discussion:
If I try this with one of our test images, it works for me without an error.

```python
from PIL import Image
im = Image.open("Tests/images/hopper.jpg")
im.save("hopper.webp")
```

Could you provide a copy of the specific JPEG image you're using?
Thank you very much for your reply, actually works!

The error turned out to be that the parameters were passed 'icc_profile', which was equal to `None`. What is strange - for JPEG files it is processed without error at all, but for some WebP files, for some reason, saving does not work. Now I will try to find out on which image to stop, I will write down in more detail.
In general - yes, apparently, WebP does not support this option at all. If you save together with the ICC profile in the JPEG, it will be saved in the final version. If you save the same image in the WebP, then the ICC profile will not be saved. If the color profile is not in the original (or rather, if you save it with the `icc_profile=None` parameter), then when you save the JPEG file, it will simply be saved without it, and in the case of WebP, there was an error that was difficult to find... 

Maybe make a more unified processing or a little more write about an error? Although, maybe it's just that I could not find it quickly... In general, everything works, thanks for the help, the issue can be closed. 🙏🏼
I've created PR #5601 to fix the `icc_profile=None` error.

It sounds like you're also having trouble saving the ICC profile to WebP. If you'd like that addressed, please provide some example code.

Resolving patch:
diff --git a/src/PIL/WebPImagePlugin.py b/src/PIL/WebPImagePlugin.py
--- a/src/PIL/WebPImagePlugin.py
+++ b/src/PIL/WebPImagePlugin.py
@@ -202,7 +202,7 @@ def _save_all(im, fp, filename):
     lossless = im.encoderinfo.get("lossless", False)
     quality = im.encoderinfo.get("quality", 80)
     method = im.encoderinfo.get("method", 0)
-    icc_profile = im.encoderinfo.get("icc_profile", "")
+    icc_profile = im.encoderinfo.get("icc_profile") or ""
     exif = im.encoderinfo.get("exif", "")
     if isinstance(exif, Image.Exif):
         exif = exif.tobytes()
@@ -309,7 +309,7 @@ def _save_all(im, fp, filename):
 def _save(im, fp, filename):
     lossless = im.encoderinfo.get("lossless", False)
     quality = im.encoderinfo.get("quality", 80)
-    icc_profile = im.encoderinfo.get("icc_profile", "")
+    icc_profile = im.encoderinfo.get("icc_profile") or ""
     exif = im.encoderinfo.get("exif", "")
     if isinstance(exif, Image.Exif):
         exif = exif.tobytes()


Test patch:
diff --git a/Tests/test_file_webp.py b/Tests/test_file_webp.py
--- a/Tests/test_file_webp.py
+++ b/Tests/test_file_webp.py
@@ -104,6 +104,13 @@ def test_write_method(self, tmp_path):
         hopper().save(buffer_method, format="WEBP", method=6)
         assert buffer_no_args.getbuffer() != buffer_method.getbuffer()
 
+    def test_icc_profile(self, tmp_path):
+        self._roundtrip(tmp_path, self.rgb_mode, 12.5, {"icc_profile": None})
+        if _webp.HAVE_WEBPANIM:
+            self._roundtrip(
+                tmp_path, self.rgb_mode, 12.5, {"icc_profile": None, "save_all": True}
+            )
+
     def test_write_unsupported_mode_L(self, tmp_path):
         """
         Saving a black-and-white file to WebP format should work, and be