Merge pull request #6747 from ashafaei/webp-params

Added WebP encoding with exact config
This commit is contained in:
mergify[bot] 2022-11-21 00:44:57 +00:00 committed by GitHub
commit 4f68047e6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 1 deletions

View File

@ -97,6 +97,35 @@ def test_write_rgba(tmp_path):
assert_image_similar(image, pil_image, 1.0)
def test_keep_rgb_values_when_transparent(tmp_path):
"""
Saving transparent pixels should retain their original RGB values
when using the "exact" parameter.
"""
image = hopper("RGB")
# create a copy of the image
# with the left half transparent
half_transparent_image = image.copy()
new_alpha = Image.new("L", (128, 128), 255)
new_alpha.paste(0, (0, 0, 64, 128))
half_transparent_image.putalpha(new_alpha)
# save with transparent area preserved
temp_file = str(tmp_path / "temp.webp")
half_transparent_image.save(temp_file, exact=True, lossless=True)
with Image.open(temp_file) as reloaded:
assert reloaded.mode == "RGBA"
assert reloaded.format == "WEBP"
# even though it is lossless, if we don't use exact=True
# in libwebp >= 0.5, the transparent area will be filled with black
# (or something more conducive to compression)
assert_image_equal(reloaded.convert("RGB"), image)
def test_write_unsupported_mode_PA(tmp_path):
"""
Saving a palette-based file with transparency to WebP format

View File

@ -1124,6 +1124,11 @@ The :py:meth:`~PIL.Image.Image.save` method supports the following options:
**method**
Quality/speed trade-off (0=fast, 6=slower-better). Defaults to 4.
**exact**
If true, preserve the transparent RGB values. Otherwise, discard
invisible RGB values for better compression. Defaults to false.
Requires libwebp 0.5.0 or later.
**icc_profile**
The ICC Profile to include in the saved file. Only supported if
the system WebP library was built with webpmux support.

View File

@ -37,6 +37,14 @@ support a ``start`` argument. This tuple of horizontal and vertical offset
will be used internally by :py:meth:`.ImageDraw.text` to more accurately place
text at the ``xy`` coordinates.
Added the ``exact`` encoding option for WebP
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The ``exact`` encoding option for WebP is now supported. The WebP encoder
removes the hidden RGB values for better compression by default in libwebp 0.5
or later. By setting this option to ``True``, the encoder will keep the hidden
RGB values.
Security
========

View File

@ -318,6 +318,7 @@ def _save(im, fp, filename):
exif = exif[6:]
xmp = im.encoderinfo.get("xmp", "")
method = im.encoderinfo.get("method", 4)
exact = 1 if im.encoderinfo.get("exact") else 0
if im.mode not in _VALID_WEBP_LEGACY_MODES:
alpha = (
@ -336,6 +337,7 @@ def _save(im, fp, filename):
im.mode,
icc_profile,
method,
exact,
exif,
xmp,
)

View File

@ -576,6 +576,7 @@ WebPEncode_wrapper(PyObject *self, PyObject *args) {
int lossless;
float quality_factor;
int method;
int exact;
uint8_t *rgb;
uint8_t *icc_bytes;
uint8_t *exif_bytes;
@ -597,7 +598,7 @@ WebPEncode_wrapper(PyObject *self, PyObject *args) {
if (!PyArg_ParseTuple(
args,
"y#iiifss#is#s#",
"y#iiifss#iis#s#",
(char **)&rgb,
&size,
&width,
@ -608,6 +609,7 @@ WebPEncode_wrapper(PyObject *self, PyObject *args) {
&icc_bytes,
&icc_size,
&method,
&exact,
&exif_bytes,
&exif_size,
&xmp_bytes,
@ -633,6 +635,10 @@ WebPEncode_wrapper(PyObject *self, PyObject *args) {
config.lossless = lossless;
config.quality = quality_factor;
config.method = method;
#if WEBP_ENCODER_ABI_VERSION >= 0x0209
// the "exact" flag is only available in libwebp 0.5.0 and later
config.exact = exact;
#endif
// Validate the config
if (!WebPValidateConfig(&config)) {