Merge branch 'box-in-thumbnail' into reduce-in-resize-2

This commit is contained in:
Alexander 2019-12-17 02:27:44 +03:00
commit 2db5406626
6 changed files with 46 additions and 13 deletions

View File

@ -13,7 +13,11 @@ class TestImageDraft(PillowTestCase):
im = Image.new(in_mode, in_size)
data = tostring(im, "JPEG")
im = fromstring(data)
im.draft(req_mode, req_size)
mode, box = im.draft(req_mode, req_size)
scale, _ = im.decoderconfig
self.assertEqual(box[:2], (0, 0))
self.assertTrue((im.width - scale) < box[2] <= im.width)
self.assertTrue((im.height - scale) < box[3] <= im.height)
return im
def test_size(self):

View File

@ -1,6 +1,6 @@
from PIL import Image
from .helper import PillowTestCase, hopper
from .helper import PillowTestCase, fromstring, hopper, tostring
class TestImageThumbnail(PillowTestCase):
@ -53,3 +53,15 @@ class TestImageThumbnail(PillowTestCase):
with Image.open("Tests/images/hopper.jpg") as im:
im.thumbnail((64, 64))
self.assertEqual(im.size, (64, 64))
def test_DCT_scaling_edges(self):
# Make an image with red borders and size (N * 8) + 1 to cross DCT grid
im = Image.new("RGB", (257, 257), "red")
im.paste(Image.new("RGB", (235, 235)), (11, 11))
thumb = fromstring(tostring(im, "JPEG", quality=99, subsampling=0))
thumb.thumbnail((32, 32), Image.BICUBIC)
ref = im.resize((32, 32), Image.BICUBIC)
# This is still JPEG, some error is present. Without the fix it is 11.5
self.assert_image_similar(thumb, ref, 1.5)

View File

@ -47,6 +47,20 @@ Setting the size of TIFF images
Setting the size of a TIFF image directly (eg. ``im.size = (256, 256)``) throws
an error. Use ``Image.resize`` instead.
Image.draft() return value
^^^^^^^^^^^^^^^^^^^^^^^^^^
The ``Image.draft()`` method used to return ``None`` or the image itself.
Unlike other `chain methods`_, ``draft()`` modifies the image in-place
rather than returning a modified version.
In the new version, ``draft()`` returns ``None`` if it has no effect or
a tuple of new image mode and the box of original coordinates in the
bounds of resulting image otherwise
(the box could be useful in subsequent ``resize()`` call).
.. _chain methods: https://en.wikipedia.org/wiki/Method_chaining
API Changes
===========

View File

@ -1126,12 +1126,15 @@ class Image:
"""
Configures the image file loader so it returns a version of the
image that as closely as possible matches the given mode and
size. For example, you can use this method to convert a color
size. For example, you can use this method to convert a color
JPEG to greyscale while loading it, or to extract a 128x192
version from a PCD file.
If any changes are made, returns a tuple with the chosen ``mode`` and
``box`` with coordinates of the original image within the altered one.
Note that this method modifies the :py:class:`~PIL.Image.Image` object
in place. If the image has already been loaded, this method has no
in place. If the image has already been loaded, this method has no
effect.
Note: This method is not implemented for most images. It is
@ -2176,14 +2179,17 @@ class Image:
x = max(round(x * size[1] / y), 1)
y = size[1]
size = x, y
box = None
if size == self.size:
return
self.draft(None, size)
res = self.draft(None, size)
if res is not None:
box = res[1]
if self.size != size:
im = self.resize(size, resample)
im = self.resize(size, resample, box=box)
self.im = im.im
self._size = size

View File

@ -122,11 +122,6 @@ class ImageFile(Image.Image):
self.fp.close()
raise
def draft(self, mode, size):
"""Set draft mode"""
pass
def get_format_mimetype(self):
if self.custom_mimetype:
return self.custom_mimetype

View File

@ -412,7 +412,8 @@ class JpegImageFile(ImageFile.ImageFile):
return
d, e, o, a = self.tile[0]
scale = 0
scale = 1
original_size = self.size
if a[0] == "RGB" and mode in ["L", "YCbCr"]:
self.mode = mode
@ -435,7 +436,8 @@ class JpegImageFile(ImageFile.ImageFile):
self.tile = [(d, e, o, a)]
self.decoderconfig = (scale, 0)
return self
box = (0, 0, original_size[0] / float(scale), original_size[1] / float(scale))
return (self.mode, box)
def load_djpeg(self):