mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-25 01:16:16 +03:00
Fix wrong formula for subsampling=2 while JPEG saving
This commit is contained in:
parent
c7136f7ff8
commit
4d56db3a34
|
@ -635,7 +635,11 @@ def _save(im, fp, filename):
|
||||||
subsampling = 0
|
subsampling = 0
|
||||||
elif subsampling == "4:2:2":
|
elif subsampling == "4:2:2":
|
||||||
subsampling = 1
|
subsampling = 1
|
||||||
|
elif subsampling == "4:2:0":
|
||||||
|
subsampling = 2
|
||||||
elif subsampling == "4:1:1":
|
elif subsampling == "4:1:1":
|
||||||
|
# For compatibility. Before Pillow 4.3, 4:1:1 actually meant 4:2:0.
|
||||||
|
# Set 4:2:0 if someone is still using that value.
|
||||||
subsampling = 2
|
subsampling = 2
|
||||||
elif subsampling == "keep":
|
elif subsampling == "keep":
|
||||||
if im.format != "JPEG":
|
if im.format != "JPEG":
|
||||||
|
|
|
@ -30,7 +30,7 @@ for chroma information than for luma information.
|
||||||
(ref.: https://en.wikipedia.org/wiki/Chroma_subsampling)
|
(ref.: https://en.wikipedia.org/wiki/Chroma_subsampling)
|
||||||
|
|
||||||
Possible subsampling values are 0, 1 and 2 that correspond to 4:4:4, 4:2:2 and
|
Possible subsampling values are 0, 1 and 2 that correspond to 4:4:4, 4:2:2 and
|
||||||
4:1:1 (or 4:2:0?).
|
4:2:0.
|
||||||
|
|
||||||
You can get the subsampling of a JPEG with the
|
You can get the subsampling of a JPEG with the
|
||||||
`JpegImagePlugin.get_subsampling(im)` function.
|
`JpegImagePlugin.get_subsampling(im)` function.
|
||||||
|
@ -67,7 +67,7 @@ Libjpeg ref.: https://web.archive.org/web/20120328125543/http://www.jpegcameras.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
presets = {
|
presets = {
|
||||||
'web_low': {'subsampling': 2, # "4:1:1"
|
'web_low': {'subsampling': 2, # "4:2:0"
|
||||||
'quantization': [
|
'quantization': [
|
||||||
[20, 16, 25, 39, 50, 46, 62, 68,
|
[20, 16, 25, 39, 50, 46, 62, 68,
|
||||||
16, 18, 23, 38, 38, 53, 65, 68,
|
16, 18, 23, 38, 38, 53, 65, 68,
|
||||||
|
@ -86,7 +86,7 @@ presets = {
|
||||||
68, 68, 68, 68, 68, 68, 68, 68,
|
68, 68, 68, 68, 68, 68, 68, 68,
|
||||||
68, 68, 68, 68, 68, 68, 68, 68]
|
68, 68, 68, 68, 68, 68, 68, 68]
|
||||||
]},
|
]},
|
||||||
'web_medium': {'subsampling': 2, # "4:1:1"
|
'web_medium': {'subsampling': 2, # "4:2:0"
|
||||||
'quantization': [
|
'quantization': [
|
||||||
[16, 11, 11, 16, 23, 27, 31, 30,
|
[16, 11, 11, 16, 23, 27, 31, 30,
|
||||||
11, 12, 12, 15, 20, 23, 23, 30,
|
11, 12, 12, 15, 20, 23, 23, 30,
|
||||||
|
@ -162,7 +162,7 @@ presets = {
|
||||||
3, 3, 3, 3, 3, 3, 3, 3,
|
3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
3, 3, 3, 3, 3, 3, 3, 3]
|
3, 3, 3, 3, 3, 3, 3, 3]
|
||||||
]},
|
]},
|
||||||
'low': {'subsampling': 2, # "4:1:1"
|
'low': {'subsampling': 2, # "4:2:0"
|
||||||
'quantization': [
|
'quantization': [
|
||||||
[18, 14, 14, 21, 30, 35, 34, 17,
|
[18, 14, 14, 21, 30, 35, 34, 17,
|
||||||
14, 16, 16, 19, 26, 23, 12, 12,
|
14, 16, 16, 19, 26, 23, 12, 12,
|
||||||
|
@ -181,7 +181,7 @@ presets = {
|
||||||
17, 12, 12, 12, 12, 12, 12, 12,
|
17, 12, 12, 12, 12, 12, 12, 12,
|
||||||
17, 12, 12, 12, 12, 12, 12, 12]
|
17, 12, 12, 12, 12, 12, 12, 12]
|
||||||
]},
|
]},
|
||||||
'medium': {'subsampling': 2, # "4:1:1"
|
'medium': {'subsampling': 2, # "4:2:0"
|
||||||
'quantization': [
|
'quantization': [
|
||||||
[12, 8, 8, 12, 17, 21, 24, 17,
|
[12, 8, 8, 12, 17, 21, 24, 17,
|
||||||
8, 9, 9, 11, 15, 19, 12, 12,
|
8, 9, 9, 11, 15, 19, 12, 12,
|
||||||
|
|
|
@ -299,7 +299,7 @@ class TestFileJpeg(PillowTestCase):
|
||||||
self.assertEqual(getsampling(im), (1, 1, 1, 1, 1, 1))
|
self.assertEqual(getsampling(im), (1, 1, 1, 1, 1, 1))
|
||||||
im = self.roundtrip(hopper(), subsampling=1) # 4:2:2
|
im = self.roundtrip(hopper(), subsampling=1) # 4:2:2
|
||||||
self.assertEqual(getsampling(im), (2, 1, 1, 1, 1, 1))
|
self.assertEqual(getsampling(im), (2, 1, 1, 1, 1, 1))
|
||||||
im = self.roundtrip(hopper(), subsampling=2) # 4:1:1
|
im = self.roundtrip(hopper(), subsampling=2) # 4:2:0
|
||||||
self.assertEqual(getsampling(im), (2, 2, 1, 1, 1, 1))
|
self.assertEqual(getsampling(im), (2, 2, 1, 1, 1, 1))
|
||||||
im = self.roundtrip(hopper(), subsampling=3) # default (undefined)
|
im = self.roundtrip(hopper(), subsampling=3) # default (undefined)
|
||||||
self.assertEqual(getsampling(im), (2, 2, 1, 1, 1, 1))
|
self.assertEqual(getsampling(im), (2, 2, 1, 1, 1, 1))
|
||||||
|
@ -308,6 +308,8 @@ class TestFileJpeg(PillowTestCase):
|
||||||
self.assertEqual(getsampling(im), (1, 1, 1, 1, 1, 1))
|
self.assertEqual(getsampling(im), (1, 1, 1, 1, 1, 1))
|
||||||
im = self.roundtrip(hopper(), subsampling="4:2:2")
|
im = self.roundtrip(hopper(), subsampling="4:2:2")
|
||||||
self.assertEqual(getsampling(im), (2, 1, 1, 1, 1, 1))
|
self.assertEqual(getsampling(im), (2, 1, 1, 1, 1, 1))
|
||||||
|
im = self.roundtrip(hopper(), subsampling="4:2:0")
|
||||||
|
self.assertEqual(getsampling(im), (2, 2, 1, 1, 1, 1))
|
||||||
im = self.roundtrip(hopper(), subsampling="4:1:1")
|
im = self.roundtrip(hopper(), subsampling="4:1:1")
|
||||||
self.assertEqual(getsampling(im), (2, 2, 1, 1, 1, 1))
|
self.assertEqual(getsampling(im), (2, 2, 1, 1, 1, 1))
|
||||||
|
|
||||||
|
|
|
@ -275,11 +275,11 @@ The :py:meth:`~PIL.Image.Image.save` method supports the following options:
|
||||||
If present, sets the subsampling for the encoder.
|
If present, sets the subsampling for the encoder.
|
||||||
|
|
||||||
* ``keep``: Only valid for JPEG files, will retain the original image setting.
|
* ``keep``: Only valid for JPEG files, will retain the original image setting.
|
||||||
* ``4:4:4``, ``4:2:2``, ``4:1:1``: Specific sampling values
|
* ``4:4:4``, ``4:2:2``, ``4:2:0``: Specific sampling values
|
||||||
* ``-1``: equivalent to ``keep``
|
* ``-1``: equivalent to ``keep``
|
||||||
* ``0``: equivalent to ``4:4:4``
|
* ``0``: equivalent to ``4:4:4``
|
||||||
* ``1``: equivalent to ``4:2:2``
|
* ``1``: equivalent to ``4:2:2``
|
||||||
* ``2``: equivalent to ``4:1:1``
|
* ``2``: equivalent to ``4:2:0``
|
||||||
|
|
||||||
**qtables**
|
**qtables**
|
||||||
If present, sets the qtables for the encoder. This is listed as an
|
If present, sets the qtables for the encoder. This is listed as an
|
||||||
|
|
|
@ -194,7 +194,7 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
context->cinfo.comp_info[2].v_samp_factor = 1;
|
context->cinfo.comp_info[2].v_samp_factor = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: /* 2x2, 1x1, 1x1 (4:1:1) : High */
|
case 2: /* 2x2, 1x1, 1x1 (4:2:0) : High */
|
||||||
{
|
{
|
||||||
context->cinfo.comp_info[0].h_samp_factor = 2;
|
context->cinfo.comp_info[0].h_samp_factor = 2;
|
||||||
context->cinfo.comp_info[0].v_samp_factor = 2;
|
context->cinfo.comp_info[0].v_samp_factor = 2;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user