updated webp with exact parameter.

This commit is contained in:
Alireza Shafaei 2022-11-17 13:58:07 -08:00
parent df8e872912
commit 1f6df76c42
4 changed files with 44 additions and 1 deletions

View File

@ -96,6 +96,40 @@ def test_write_rgba(tmp_path):
else:
assert_image_similar(image, pil_image, 1.0)
def test_write_rgba_keep_transparent(tmp_path):
"""
Can we write a RGBA mode file to WebP while preserving
the transparent RGB without error.
Does it have the bits we expect?
"""
temp_output_file = str(tmp_path / "temp.webp")
input_image = hopper("RGB")
# make a copy of the image
output_image = input_image.copy()
# make a single channel image with the same size as input_image
new_alpha = Image.new("L", input_image.size, 255)
# make the left half transparent
new_alpha.paste((0,), (0, 0, new_alpha.size[0]//2, new_alpha.size[1]))
# putalpha on output_image
output_image.putalpha(new_alpha)
# now save with transparent area preserved.
output_image.save(temp_output_file, "WEBP", exact=True, lossless=True)
# even though it is lossless, if we don't put exact=True, the transparent
# area will be filled with black (or something more conducive to compression)
with Image.open(temp_output_file) as image:
image.load()
assert image.mode == "RGBA"
assert image.format == "WEBP"
image.load()
image = image.convert("RGB")
assert_image_similar(image, input_image, 1.0)
def test_write_unsupported_mode_PA(tmp_path):
"""

View File

@ -1124,6 +1124,10 @@ 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.
**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

@ -318,6 +318,7 @@ def _save(im, fp, filename):
exif = exif[6:]
xmp = im.encoderinfo.get("xmp", "")
method = im.encoderinfo.get("method", 4)
exact = im.encoderinfo.get("exact", False)
if im.mode not in _VALID_WEBP_LEGACY_MODES:
alpha = (
@ -336,6 +337,7 @@ def _save(im, fp, filename):
im.mode,
icc_profile,
method,
1 if exact else 0,
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,7 @@ WebPEncode_wrapper(PyObject *self, PyObject *args) {
config.lossless = lossless;
config.quality = quality_factor;
config.method = method;
config.exact = exact;
// Validate the config
if (!WebPValidateConfig(&config)) {