Merge pull request #3298 from kkopachev/webp-rgb

Read/save RGB webp as RGB (instead of RGBX)
This commit is contained in:
Hugo 2018-09-17 12:05:07 +03:00 committed by GitHub
commit 521ae77bb9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 24 additions and 22 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

@ -16,8 +16,7 @@ class TestFileWebp(PillowTestCase):
self.skipTest('WebP support not installed')
return
# WebPAnimDecoder only returns RGBA or RGBX, never RGB
self.rgb_mode = "RGBX" if _webp.HAVE_WEBPANIM else "RGB"
self.rgb_mode = "RGB"
def test_version(self):
_webp.WebPDecoderVersion()
@ -29,8 +28,7 @@ class TestFileWebp(PillowTestCase):
Does it have the bits we expect?
"""
file_path = "Tests/images/hopper.webp"
image = Image.open(file_path)
image = Image.open("Tests/images/hopper.webp")
self.assertEqual(image.mode, self.rgb_mode)
self.assertEqual(image.size, (128, 128))
@ -40,9 +38,7 @@ class TestFileWebp(PillowTestCase):
# generated with:
# dwebp -ppm ../../Tests/images/hopper.webp -o hopper_webp_bits.ppm
target = Image.open('Tests/images/hopper_webp_bits.ppm')
target = target.convert(self.rgb_mode)
self.assert_image_similar(image, target, 20.0)
self.assert_image_similar_tofile(image, 'Tests/images/hopper_webp_bits.ppm', 1.0)
def test_write_rgb(self):
"""
@ -61,13 +57,8 @@ class TestFileWebp(PillowTestCase):
image.load()
image.getdata()
# If we're using the exact same version of WebP, this test should pass.
# but it doesn't if the WebP is generated on Ubuntu and tested on
# Fedora.
# generated with: dwebp -ppm temp.webp -o hopper_webp_write.ppm
# target = Image.open('Tests/images/hopper_webp_write.ppm')
# self.assert_image_equal(image, target)
self.assert_image_similar_tofile(image, 'Tests/images/hopper_webp_write.ppm', 12.0)
# This test asserts that the images are similar. If the average pixel
# difference between the two images is less than the epsilon value,

View File

@ -19,8 +19,7 @@ class TestFileWebpLossless(PillowTestCase):
if (_webp.WebPDecoderVersion() < 0x0200):
self.skipTest('lossless not included')
# WebPAnimDecoder only returns RGBA or RGBX, never RGB
self.rgb_mode = "RGBX" if _webp.HAVE_WEBPANIM else "RGB"
self.rgb_mode = "RGB"
def test_write_lossless_rgb(self):
temp_file = self.tempfile("temp.webp")

View File

@ -5,6 +5,7 @@ from io import BytesIO
_VALID_WEBP_MODES = {
"RGBX": True,
"RGBA": True,
"RGB": True,
}
_VALID_WEBP_LEGACY_MODES = {
@ -63,7 +64,8 @@ class WebPImageFile(ImageFile.ImageFile):
bgcolor & 0xFF
self.info["background"] = (bg_r, bg_g, bg_b, bg_a)
self._n_frames = frame_count
self.mode = mode
self.mode = 'RGB' if mode == 'RGBX' else mode
self.rawmode = mode
self.tile = []
# Attempt to read ICC / EXIF / XMP chunks from file
@ -156,7 +158,7 @@ class WebPImageFile(ImageFile.ImageFile):
if self.fp:
self.fp.close()
self.fp = BytesIO(data)
self.tile = [("raw", (0, 0) + self.size, 0, self.mode)]
self.tile = [("raw", (0, 0) + self.size, 0, self.rawmode)]
return super(WebPImageFile, self).load()
@ -242,16 +244,23 @@ def _save_all(im, fp, filename):
# Make sure image mode is supported
frame = ims
rawmode = ims.mode
if ims.mode not in _VALID_WEBP_MODES:
alpha = ims.mode == 'P' and 'A' in ims.im.getpalettemode()
frame = ims.convert('RGBA' if alpha else 'RGBX')
alpha = 'A' in ims.mode or 'a' in ims.mode \
or (ims.mode == 'P' and 'A' in ims.im.getpalettemode())
rawmode = 'RGBA' if alpha else 'RGB'
frame = ims.convert(rawmode)
if rawmode == 'RGB':
# For faster conversion, use RGBX
rawmode = 'RGBX'
# Append the frame to the animation encoder
enc.add(
frame.tobytes(),
frame.tobytes('raw', rawmode),
timestamp,
frame.size[0], frame.size[1],
frame.mode,
rawmode,
lossless,
quality,
method
@ -290,7 +299,8 @@ def _save(im, fp, filename):
xmp = im.encoderinfo.get("xmp", "")
if im.mode not in _VALID_WEBP_LEGACY_MODES:
alpha = im.mode == 'P' and 'A' in im.im.getpalettemode()
alpha = 'A' in im.mode or 'a' in im.mode \
or (im.mode == 'P' and 'A' in im.im.getpalettemode())
im = im.convert('RGBA' if alpha else 'RGB')
data = _webp.WebPEncode(

View File

@ -216,6 +216,8 @@ PyObject* _anim_encoder_add(PyObject* self, PyObject* args)
WebPPictureImportRGBA(frame, rgb, 4 * width);
} else if (strcmp(mode, "RGBX")==0) {
WebPPictureImportRGBX(frame, rgb, 4 * width);
} else {
WebPPictureImportRGB(frame, rgb, 3 * width);
}
// Add the frame to the encoder