mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-11-10 19:56:47 +03:00
Merge pull request #390 from wiredfool/webp-lossless
Lossless WEBP Support
This commit is contained in:
commit
e3d85700b4
|
@ -12,6 +12,7 @@ _VALID_WEBP_MODES = {
|
||||||
_VP8_MODES_BY_IDENTIFIER = {
|
_VP8_MODES_BY_IDENTIFIER = {
|
||||||
b"VP8 ": "RGB",
|
b"VP8 ": "RGB",
|
||||||
b"VP8X": "RGBA",
|
b"VP8X": "RGBA",
|
||||||
|
b"VP8L": "RGBA", # lossless
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,26 @@ def test_write_rgb():
|
||||||
assert_image_similar(image, target, 20.0)
|
assert_image_similar(image, target, 20.0)
|
||||||
|
|
||||||
|
|
||||||
|
def test_write_lossless_rgb():
|
||||||
|
temp_file = tempfile("temp.webp")
|
||||||
|
|
||||||
|
lena("RGB").save(temp_file, lossless=True)
|
||||||
|
|
||||||
|
image = Image.open(temp_file)
|
||||||
|
image.load()
|
||||||
|
|
||||||
|
assert_equal(image.mode, "RGB")
|
||||||
|
assert_equal(image.size, (128, 128))
|
||||||
|
assert_equal(image.format, "WEBP")
|
||||||
|
assert_no_exception(lambda: image.load())
|
||||||
|
assert_no_exception(lambda: image.getdata())
|
||||||
|
|
||||||
|
|
||||||
|
assert_image_equal(image, lena("RGB"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_write_rgba():
|
def test_write_rgba():
|
||||||
"""
|
"""
|
||||||
Can we write a RGBA mode file to webp without error. Does it have the bits we
|
Can we write a RGBA mode file to webp without error. Does it have the bits we
|
||||||
|
@ -111,3 +131,27 @@ def test_read_rgba():
|
||||||
target = Image.open('Images/transparent.png')
|
target = Image.open('Images/transparent.png')
|
||||||
assert_image_similar(image, target, 20.0)
|
assert_image_similar(image, target, 20.0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_write_lossless_rgb():
|
||||||
|
temp_file = tempfile("temp.webp")
|
||||||
|
#temp_file = "temp.webp"
|
||||||
|
|
||||||
|
pil_image = lena('RGBA')
|
||||||
|
|
||||||
|
mask = Image.new("RGBA", (64, 64), (128,128,128,128))
|
||||||
|
pil_image.paste(mask, (0,0), mask) # add some partially transparent bits.
|
||||||
|
|
||||||
|
pil_image.save(temp_file, lossless=True)
|
||||||
|
|
||||||
|
image = Image.open(temp_file)
|
||||||
|
image.load()
|
||||||
|
|
||||||
|
assert_equal(image.mode, "RGBA")
|
||||||
|
assert_equal(image.size, pil_image.size)
|
||||||
|
assert_equal(image.format, "WEBP")
|
||||||
|
assert_no_exception(lambda: image.load())
|
||||||
|
assert_no_exception(lambda: image.getdata())
|
||||||
|
|
||||||
|
|
||||||
|
assert_image_equal(image, pil_image)
|
||||||
|
|
6
_webp.c
6
_webp.c
|
@ -25,7 +25,7 @@ PyObject* WebPEncode_wrapper(PyObject* self, PyObject* args)
|
||||||
Py_ssize_t exif_size;
|
Py_ssize_t exif_size;
|
||||||
size_t ret_size;
|
size_t ret_size;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s#iiOfss#s#",
|
if (!PyArg_ParseTuple(args, "s#iiifss#s#",
|
||||||
(char**)&rgb, &size, &width, &height, &lossless, &quality_factor, &mode,
|
(char**)&rgb, &size, &width, &height, &lossless, &quality_factor, &mode,
|
||||||
&icc_bytes, &icc_size, &exif_bytes, &exif_size)) {
|
&icc_bytes, &icc_size, &exif_bytes, &exif_size)) {
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
@ -34,7 +34,7 @@ PyObject* WebPEncode_wrapper(PyObject* self, PyObject* args)
|
||||||
if (size < width * height * 4){
|
if (size < width * height * 4){
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
if (PyObject_IsTrue(lossless)) {
|
if (lossless) {
|
||||||
ret_size = WebPEncodeLosslessRGBA(rgb, width, height, 4* width, &output);
|
ret_size = WebPEncodeLosslessRGBA(rgb, width, height, 4* width, &output);
|
||||||
} else {
|
} else {
|
||||||
ret_size = WebPEncodeRGBA(rgb, width, height, 4* width, quality_factor, &output);
|
ret_size = WebPEncodeRGBA(rgb, width, height, 4* width, quality_factor, &output);
|
||||||
|
@ -43,7 +43,7 @@ PyObject* WebPEncode_wrapper(PyObject* self, PyObject* args)
|
||||||
if (size < width * height * 3){
|
if (size < width * height * 3){
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
if (PyObject_IsTrue(lossless)) {
|
if (lossless) {
|
||||||
ret_size = WebPEncodeLosslessRGB(rgb, width, height, 3* width, &output);
|
ret_size = WebPEncodeLosslessRGB(rgb, width, height, 3* width, &output);
|
||||||
} else {
|
} else {
|
||||||
ret_size = WebPEncodeRGB(rgb, width, height, 3* width, quality_factor, &output);
|
ret_size = WebPEncodeRGB(rgb, width, height, 3* width, quality_factor, &output);
|
||||||
|
|
|
@ -271,6 +271,24 @@ WebP
|
||||||
PIL reads and writes WebP files. The specifics of PIL's capabilities with this
|
PIL reads and writes WebP files. The specifics of PIL's capabilities with this
|
||||||
format are currently undocumented.
|
format are currently undocumented.
|
||||||
|
|
||||||
|
The :py:meth:`~PIL.Image.Image.save` method supports the following options:
|
||||||
|
|
||||||
|
**lossless**
|
||||||
|
If present, instructs the WEBP writer to use lossless
|
||||||
|
compression.
|
||||||
|
|
||||||
|
**quality**
|
||||||
|
Integer, 1-100, Defaults to 80. Sets the quality level for
|
||||||
|
lossy compression.
|
||||||
|
|
||||||
|
**icc_procfile**
|
||||||
|
The ICC Profile to include in the saved file. Only supported if
|
||||||
|
the system webp library was built with webpmux support.
|
||||||
|
|
||||||
|
**exif**
|
||||||
|
The exif data to include in the saved file. Only supported if
|
||||||
|
the system webp library was built with webpmux support.
|
||||||
|
|
||||||
XBM
|
XBM
|
||||||
^^^
|
^^^
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user