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: else:
assert_image_similar(image, pil_image, 1.0) 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): 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** **method**
Quality/speed trade-off (0=fast, 6=slower-better). Defaults to 4. 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** **icc_profile**
The ICC Profile to include in the saved file. Only supported if The ICC Profile to include in the saved file. Only supported if
the system WebP library was built with webpmux support. the system WebP library was built with webpmux support.

View File

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

View File

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