mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-26 01:04:29 +03:00
Read/Save RGB webp as RGB (instead of RGBX)
This commit is contained in:
parent
43f860fce6
commit
84b32a0388
Binary file not shown.
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 48 KiB |
|
@ -16,8 +16,7 @@ class TestFileWebp(PillowTestCase):
|
||||||
self.skipTest('WebP support not installed')
|
self.skipTest('WebP support not installed')
|
||||||
return
|
return
|
||||||
|
|
||||||
# WebPAnimDecoder only returns RGBA or RGBX, never RGB
|
self.rgb_mode = "RGB"
|
||||||
self.rgb_mode = "RGBX" if _webp.HAVE_WEBPANIM else "RGB"
|
|
||||||
|
|
||||||
def test_version(self):
|
def test_version(self):
|
||||||
_webp.WebPDecoderVersion()
|
_webp.WebPDecoderVersion()
|
||||||
|
@ -29,8 +28,7 @@ class TestFileWebp(PillowTestCase):
|
||||||
Does it have the bits we expect?
|
Does it have the bits we expect?
|
||||||
"""
|
"""
|
||||||
|
|
||||||
file_path = "Tests/images/hopper.webp"
|
image = Image.open("Tests/images/hopper.webp")
|
||||||
image = Image.open(file_path)
|
|
||||||
|
|
||||||
self.assertEqual(image.mode, self.rgb_mode)
|
self.assertEqual(image.mode, self.rgb_mode)
|
||||||
self.assertEqual(image.size, (128, 128))
|
self.assertEqual(image.size, (128, 128))
|
||||||
|
@ -40,9 +38,7 @@ class TestFileWebp(PillowTestCase):
|
||||||
|
|
||||||
# generated with:
|
# generated with:
|
||||||
# dwebp -ppm ../../Tests/images/hopper.webp -o hopper_webp_bits.ppm
|
# dwebp -ppm ../../Tests/images/hopper.webp -o hopper_webp_bits.ppm
|
||||||
target = Image.open('Tests/images/hopper_webp_bits.ppm')
|
self.assert_image_similar_tofile(image, 'Tests/images/hopper_webp_bits.ppm', 1.0)
|
||||||
target = target.convert(self.rgb_mode)
|
|
||||||
self.assert_image_similar(image, target, 20.0)
|
|
||||||
|
|
||||||
def test_write_rgb(self):
|
def test_write_rgb(self):
|
||||||
"""
|
"""
|
||||||
|
@ -61,13 +57,8 @@ class TestFileWebp(PillowTestCase):
|
||||||
image.load()
|
image.load()
|
||||||
image.getdata()
|
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
|
# generated with: dwebp -ppm temp.webp -o hopper_webp_write.ppm
|
||||||
# target = Image.open('Tests/images/hopper_webp_write.ppm')
|
self.assert_image_similar_tofile(image, 'Tests/images/hopper_webp_write.ppm', 12.0)
|
||||||
# self.assert_image_equal(image, target)
|
|
||||||
|
|
||||||
# This test asserts that the images are similar. If the average pixel
|
# This test asserts that the images are similar. If the average pixel
|
||||||
# difference between the two images is less than the epsilon value,
|
# difference between the two images is less than the epsilon value,
|
||||||
|
|
|
@ -19,8 +19,7 @@ class TestFileWebpLossless(PillowTestCase):
|
||||||
if (_webp.WebPDecoderVersion() < 0x0200):
|
if (_webp.WebPDecoderVersion() < 0x0200):
|
||||||
self.skipTest('lossless not included')
|
self.skipTest('lossless not included')
|
||||||
|
|
||||||
# WebPAnimDecoder only returns RGBA or RGBX, never RGB
|
self.rgb_mode = "RGB"
|
||||||
self.rgb_mode = "RGBX" if _webp.HAVE_WEBPANIM else "RGB"
|
|
||||||
|
|
||||||
def test_write_lossless_rgb(self):
|
def test_write_lossless_rgb(self):
|
||||||
temp_file = self.tempfile("temp.webp")
|
temp_file = self.tempfile("temp.webp")
|
||||||
|
|
|
@ -5,6 +5,7 @@ from io import BytesIO
|
||||||
_VALID_WEBP_MODES = {
|
_VALID_WEBP_MODES = {
|
||||||
"RGBX": True,
|
"RGBX": True,
|
||||||
"RGBA": True,
|
"RGBA": True,
|
||||||
|
"RGB": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
_VALID_WEBP_LEGACY_MODES = {
|
_VALID_WEBP_LEGACY_MODES = {
|
||||||
|
@ -63,7 +64,8 @@ class WebPImageFile(ImageFile.ImageFile):
|
||||||
bgcolor & 0xFF
|
bgcolor & 0xFF
|
||||||
self.info["background"] = (bg_r, bg_g, bg_b, bg_a)
|
self.info["background"] = (bg_r, bg_g, bg_b, bg_a)
|
||||||
self._n_frames = frame_count
|
self._n_frames = frame_count
|
||||||
self.mode = mode
|
self.mode = 'RGB' if mode == 'RGBX' else mode
|
||||||
|
self.rawmode = mode
|
||||||
self.tile = []
|
self.tile = []
|
||||||
|
|
||||||
# Attempt to read ICC / EXIF / XMP chunks from file
|
# Attempt to read ICC / EXIF / XMP chunks from file
|
||||||
|
@ -154,7 +156,7 @@ class WebPImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
# Set tile
|
# Set tile
|
||||||
self.fp = BytesIO(data)
|
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()
|
return super(WebPImageFile, self).load()
|
||||||
|
|
||||||
|
@ -240,16 +242,23 @@ def _save_all(im, fp, filename):
|
||||||
|
|
||||||
# Make sure image mode is supported
|
# Make sure image mode is supported
|
||||||
frame = ims
|
frame = ims
|
||||||
|
rawmode = ims.mode
|
||||||
if ims.mode not in _VALID_WEBP_MODES:
|
if ims.mode not in _VALID_WEBP_MODES:
|
||||||
alpha = ims.mode == 'P' and 'A' in ims.im.getpalettemode()
|
alpha = 'A' in ims.mode or 'a' in ims.mode \
|
||||||
frame = ims.convert('RGBA' if alpha else 'RGBX')
|
or ims.mode == 'P' and 'A' in ims.im.getpalettemode()
|
||||||
|
rawmode = 'RGBA' if alpha else 'RGBX'
|
||||||
|
frame = ims.convert(rawmode)
|
||||||
|
|
||||||
|
if rawmode == 'RGB':
|
||||||
|
# For faster conversion, use RGBX
|
||||||
|
rawmode = 'RGBX'
|
||||||
|
|
||||||
# Append the frame to the animation encoder
|
# Append the frame to the animation encoder
|
||||||
enc.add(
|
enc.add(
|
||||||
frame.tobytes(),
|
frame.tobytes('raw', rawmode),
|
||||||
timestamp,
|
timestamp,
|
||||||
frame.size[0], frame.size[1],
|
frame.size[0], frame.size[1],
|
||||||
frame.mode,
|
rawmode,
|
||||||
lossless,
|
lossless,
|
||||||
quality,
|
quality,
|
||||||
method
|
method
|
||||||
|
@ -288,7 +297,8 @@ def _save(im, fp, filename):
|
||||||
xmp = im.encoderinfo.get("xmp", "")
|
xmp = im.encoderinfo.get("xmp", "")
|
||||||
|
|
||||||
if im.mode not in _VALID_WEBP_LEGACY_MODES:
|
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')
|
im = im.convert('RGBA' if alpha else 'RGB')
|
||||||
|
|
||||||
data = _webp.WebPEncode(
|
data = _webp.WebPEncode(
|
||||||
|
|
|
@ -216,6 +216,8 @@ PyObject* _anim_encoder_add(PyObject* self, PyObject* args)
|
||||||
WebPPictureImportRGBA(frame, rgb, 4 * width);
|
WebPPictureImportRGBA(frame, rgb, 4 * width);
|
||||||
} else if (strcmp(mode, "RGBX")==0) {
|
} else if (strcmp(mode, "RGBX")==0) {
|
||||||
WebPPictureImportRGBX(frame, rgb, 4 * width);
|
WebPPictureImportRGBX(frame, rgb, 4 * width);
|
||||||
|
} else {
|
||||||
|
WebPPictureImportRGB(frame, rgb, 3 * width);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the frame to the encoder
|
// Add the frame to the encoder
|
||||||
|
|
Loading…
Reference in New Issue
Block a user