Avoid potential downscaling artifacts by cropping

This commit is contained in:
Andrew Murray 2019-01-05 16:46:06 +11:00
parent 2e17e0f618
commit 280633dcdf
2 changed files with 21 additions and 0 deletions

View File

@ -581,6 +581,11 @@ class TestFileJpeg(PillowTestCase):
# OSError for unidentified image. # OSError for unidentified image.
self.assertEqual(im.info.get("dpi"), (72, 72)) self.assertEqual(im.info.get("dpi"), (72, 72))
def test_partial_mcu_draft(self):
im = Image.open("Tests/images/flower2.jpg")
im.draft(im.mode, (100, 100))
self.assertEqual(im.size, (146, 109))
@unittest.skipUnless(sys.platform.startswith('win32'), "Windows only") @unittest.skipUnless(sys.platform.startswith('win32'), "Windows only")
class TestFileCloseW32(PillowTestCase): class TestFileCloseW32(PillowTestCase):

View File

@ -385,6 +385,7 @@ class JpegImageFile(ImageFile.ImageFile):
a = mode, "" a = mode, ""
if size: if size:
original_size = self.size
scale = min(self.size[0] // size[0], self.size[1] // size[1]) scale = min(self.size[0] // size[0], self.size[1] // size[1])
for s in [8, 4, 2, 1]: for s in [8, 4, 2, 1]:
if scale >= s: if scale >= s:
@ -396,6 +397,21 @@ class JpegImageFile(ImageFile.ImageFile):
self.tile = [(d, e, o, a)] self.tile = [(d, e, o, a)]
self.decoderconfig = (scale, 0) self.decoderconfig = (scale, 0)
if scale > 1:
sampling = get_sampling(self)
if sampling != -1:
mcu = [(8, 8), (16, 8), (16, 16)][sampling]
new_size = list(self.size)
for i in range(0, 2):
# If an original image dimension is not a whole number of
# MCUs, then the additional data may not be correct.
if original_size[i] % mcu[i] != 0:
new_size[i] -= mcu[i] / scale
if new_size != list(self.size):
self.load()
self._size = tuple(new_size)
self.im = self._crop(self.im, (0, 0) + self._size)
return self return self
def load_djpeg(self): def load_djpeg(self):