Pillow/PIL/WebPImagePlugin.py
Bernardo Heynemann b4735f7829 Adding support for metadata in webp images.
Pillow now uses the webpmux library to envelop the webp images in RIFF. This allows for easy support of exif and icc_profile metadata.

Also included tests that verify compatibility with jpeg for exif and icc_profile metadata.

If the user does not have webp with webpmux enabled, pillow will fall back to the previous approach, meaning no exif or icc_profile metadata will be read or written to.
2013-07-04 18:04:07 -03:00

75 lines
1.8 KiB
Python

from PIL import Image
from PIL import ImageFile
from io import BytesIO
from PIL import _webp
_VALID_WEBP_MODES = {
"RGB": True,
"RGBA": True,
}
_VP8_MODES_BY_IDENTIFIER = {
b"VP8 ": "RGB",
b"VP8X": "RGBA",
}
def _accept(prefix):
is_riff_file_format = prefix[:4] == b"RIFF"
is_webp_file = prefix[8:12] == b"WEBP"
is_valid_vp8_mode = prefix[12:16] in _VP8_MODES_BY_IDENTIFIER
return is_riff_file_format and is_webp_file and is_valid_vp8_mode
class WebPImageFile(ImageFile.ImageFile):
format = "WEBP"
format_description = "WebP image"
def _open(self):
data, width, height, self.mode, icc_profile, exif = _webp.WebPDecode(self.fp.read())
self.info["icc_profile"] = icc_profile
self.info["exif"] = exif
self.size = width, height
self.fp = BytesIO(data)
self.tile = [("raw", (0, 0) + self.size, 0, self.mode)]
def _getexif(self):
from PIL.JpegImagePlugin import JpegImageFile
return JpegImageFile._getexif.im_func(self)
def _save(im, fp, filename):
image_mode = im.mode
if im.mode not in _VALID_WEBP_MODES:
raise IOError("cannot write mode %s as WEBP" % image_mode)
quality = im.encoderinfo.get("quality", 80)
icc_profile = im.encoderinfo.get("icc_profile", "")
exif = im.encoderinfo.get("exif", "")
data = _webp.WebPEncode(
im.tobytes(),
im.size[0],
im.size[1],
float(quality),
im.mode,
icc_profile,
exif
)
if data is None:
raise IOError("cannot write file as WEBP (encoder returned None)")
fp.write(data)
Image.register_open("WEBP", WebPImageFile, _accept)
Image.register_save("WEBP", _save)
Image.register_extension("WEBP", ".webp")
Image.register_mime("WEBP", "image/webp")