From 50d6611587424394be1fdd93255b32f96ea7e34f Mon Sep 17 00:00:00 2001 From: tsennott Date: Mon, 9 Jul 2018 07:04:48 -0700 Subject: [PATCH] moved tuple test to assert method in PillowTestCase; added docs --- Tests/helper.py | 19 ++++----- Tests/test_imageops.py | 79 +++++++++++++++++++++---------------- docs/releasenotes/5.3.0.rst | 39 ++++++++++++++++++ docs/releasenotes/index.rst | 1 + src/PIL/ImageOps.py | 5 ++- 5 files changed, 98 insertions(+), 45 deletions(-) create mode 100644 docs/releasenotes/5.3.0.rst diff --git a/Tests/helper.py b/Tests/helper.py index 834589723..b6ef6dc13 100644 --- a/Tests/helper.py +++ b/Tests/helper.py @@ -192,6 +192,16 @@ class PillowTestCase(unittest.TestCase): def assert_not_all_same(self, items, msg=None): self.assertFalse(items.count(items[0]) == len(items), msg) + def assert_tuple_approx_equal(self, actuals, targets, threshold, msg): + """Tests if actuals has values within threshold from targets""" + + value = True + for i, target in enumerate(targets): + value *= (target - threshold <= actuals[i] <= target + threshold) + + self.assertTrue(value, + msg + ': ' + repr(actuals) + ' != ' + repr(targets)) + def skipKnownBadTest(self, msg=None, platform=None, travis=None, interpreter=None): # Skip if platform/travis matches, and @@ -307,15 +317,6 @@ def hopper(mode=None, cache={}): return im.copy() -def tuple_approx_equal(actual, target, threshold): - """Tests if tuple actual has values within threshold from tuple target""" - - value = True - for i, target in enumerate(target): - value *= (target - threshold <= actual[i] <= target + threshold) - return value - - def command_succeeds(cmd): """ Runs the command, which must be a list of strings. Returns True if the diff --git a/Tests/test_imageops.py b/Tests/test_imageops.py index 07e4dd343..9c4da2463 100644 --- a/Tests/test_imageops.py +++ b/Tests/test_imageops.py @@ -1,4 +1,4 @@ -from helper import unittest, PillowTestCase, hopper, tuple_approx_equal +from helper import unittest, PillowTestCase, hopper from PIL import ImageOps from PIL import Image @@ -109,15 +109,18 @@ class TestImageOps(PillowTestCase): left = (0, 1) middle = (127, 1) right = (255, 1) - self.assertTrue(tuple_approx_equal(im_test.getpixel(left), - (255, 0, 0), threshold=1), - '2-color image black incorrect') - self.assertTrue(tuple_approx_equal(im_test.getpixel(middle), - (127, 63, 0), threshold=1), - '2-color image mid incorrect') - self.assertTrue(tuple_approx_equal(im_test.getpixel(right), - (0, 127, 0), threshold=1), - '2-color image white incorrect') + self.assert_tuple_approx_equal(im_test.getpixel(left), + (255, 0, 0), + threshold=1, + msg='black test pixel incorrect') + self.assert_tuple_approx_equal(im_test.getpixel(middle), + (127, 63, 0), + threshold=1, + msg='mid test pixel incorrect') + self.assert_tuple_approx_equal(im_test.getpixel(right), + (0, 127, 0), + threshold=1, + msg='white test pixel incorrect') def test_colorize_2color_offset(self): # Test the colorizing function with 2-color functionality and offset @@ -137,15 +140,18 @@ class TestImageOps(PillowTestCase): left = (25, 1) middle = (75, 1) right = (125, 1) - self.assertTrue(tuple_approx_equal(im_test.getpixel(left), - (255, 0, 0), threshold=1), - '2-color image (with offset) black incorrect') - self.assertTrue(tuple_approx_equal(im_test.getpixel(middle), - (127, 63, 0), threshold=1), - '2-color image (with offset) mid incorrect') - self.assertTrue(tuple_approx_equal(im_test.getpixel(right), - (0, 127, 0), threshold=1), - '2-color image (with offset) white incorrect') + self.assert_tuple_approx_equal(im_test.getpixel(left), + (255, 0, 0), + threshold=1, + msg='black test pixel incorrect') + self.assert_tuple_approx_equal(im_test.getpixel(middle), + (127, 63, 0), + threshold=1, + msg='mid test pixel incorrect') + self.assert_tuple_approx_equal(im_test.getpixel(right), + (0, 127, 0), + threshold=1, + msg='white test pixel incorrect') def test_colorize_3color_offset(self): # Test the colorizing function with 3-color functionality and offset @@ -169,21 +175,26 @@ class TestImageOps(PillowTestCase): middle = (100, 1) right_middle = (150, 1) right = (225, 1) - self.assertTrue(tuple_approx_equal(im_test.getpixel(left), - (255, 0, 0), threshold=1), - '3-color image (with offset) black incorrect') - self.assertTrue(tuple_approx_equal(im_test.getpixel(left_middle), - (127, 0, 127), threshold=1), - '3-color image (with offset) low-mid incorrect') - self.assertTrue(tuple_approx_equal(im_test.getpixel(middle), - (0, 0, 255), threshold=1), - '3-color image (with offset) mid incorrect') - self.assertTrue(tuple_approx_equal(im_test.getpixel(right_middle), - (0, 63, 127), threshold=1), - '3-color image (with offset) high-mid incorrect') - self.assertTrue(tuple_approx_equal(im_test.getpixel(right), - (0, 127, 0), threshold=1), - '3-color image (with offset) white incorrect') + self.assert_tuple_approx_equal(im_test.getpixel(left), + (255, 0, 0), + threshold=1, + msg='black test pixel incorrect') + self.assert_tuple_approx_equal(im_test.getpixel(left_middle), + (127, 0, 127), + threshold=1, + msg='low-mid test pixel incorrect') + self.assert_tuple_approx_equal(im_test.getpixel(middle), + (0, 0, 255), + threshold=1, + msg='mid incorrect') + self.assert_tuple_approx_equal(im_test.getpixel(right_middle), + (0, 63, 127), + threshold=1, + msg='high-mid test pixel incorrect') + self.assert_tuple_approx_equal(im_test.getpixel(right), + (0, 127, 0), + threshold=1, + msg='white test pixel incorrect') if __name__ == '__main__': diff --git a/docs/releasenotes/5.3.0.rst b/docs/releasenotes/5.3.0.rst new file mode 100644 index 000000000..9869b6a7a --- /dev/null +++ b/docs/releasenotes/5.3.0.rst @@ -0,0 +1,39 @@ +5.3.0 +----- + +API Changes +=========== + +Deprecations +^^^^^^^^^^^^ + +These version constants have been deprecated. ``VERSION`` will be removed in +Pillow 6.0.0, and ``PILLOW_VERSION`` will be removed after that. + +* ``PIL.VERSION`` (old PIL version 1.1.7) +* ``PIL.PILLOW_VERSION`` +* ``PIL.Image.VERSION`` +* ``PIL.Image.PILLOW_VERSION`` + +Use ``PIL.__version__`` instead. + +API Additions +============= + +ImageOps.colorize +^^^^^^^^^^^^^^^^^ + +Previously ``ImageOps.colorize`` only supported two-color mapping with +``black`` and ``white`` arguments being mapped to 0 and 255 respectively. +Now it supports three-color mapping with the optional ``mid`` parameter, and +the positions for all three color arguments can each be optionally specified +(``blackpoint``, ``whitepoint`` and ``midpoint``). +For example, with all optional arguments:: + ImageOps.colorize(im, black=(32, 37, 79), white='white', mid=(59, 101, 175), + blackpoint=15, whitepoint=240, midpoint=100) + + + +Other Changes +============= + diff --git a/docs/releasenotes/index.rst b/docs/releasenotes/index.rst index 16e5c1d85..fc8d686eb 100644 --- a/docs/releasenotes/index.rst +++ b/docs/releasenotes/index.rst @@ -6,6 +6,7 @@ Release Notes .. toctree:: :maxdepth: 2 + 5.3.0 5.2.0 5.1.0 5.0.0 diff --git a/src/PIL/ImageOps.py b/src/PIL/ImageOps.py index 0ba7ce069..9b470062a 100644 --- a/src/PIL/ImageOps.py +++ b/src/PIL/ImageOps.py @@ -147,8 +147,9 @@ def colorize(image, black, white, mid=None, blackpoint=0, optionally you can use three-color mapping by also specifying **mid**. Mapping positions for any of the colors can be specified (e.g. **blackpoint**), where these parameters are the integer - value in [0, 255] corresponding to where the corresponding color - should be mapped. + value corresponding to where the corresponding color should be mapped. + These parameters must have logical order, such that + **blackpoint** <= **midpoint** <= **whitepoint** (if **mid** is specified). :param image: The image to colorize. :param black: The color to use for black input pixels.