mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-27 10:26:19 +03:00
tightened up colorize(); split tests; moved tuple comparison fcn to helper.py
This commit is contained in:
parent
4a6ec5ca72
commit
1eed17c70e
|
@ -307,6 +307,15 @@ def hopper(mode=None, cache={}):
|
||||||
return im.copy()
|
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):
|
def command_succeeds(cmd):
|
||||||
"""
|
"""
|
||||||
Runs the command, which must be a list of strings. Returns True if the
|
Runs the command, which must be a list of strings. Returns True if the
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from helper import unittest, PillowTestCase, hopper
|
from helper import unittest, PillowTestCase, hopper, tuple_approx_equal
|
||||||
|
|
||||||
from PIL import ImageOps
|
from PIL import ImageOps
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
@ -95,87 +95,94 @@ class TestImageOps(PillowTestCase):
|
||||||
newimg = ImageOps.scale(i, 0.5)
|
newimg = ImageOps.scale(i, 0.5)
|
||||||
self.assertEqual(newimg.size, (25, 25))
|
self.assertEqual(newimg.size, (25, 25))
|
||||||
|
|
||||||
def test_colorize(self):
|
def test_colorize_2color(self):
|
||||||
# Test the colorizing function
|
# Test the colorizing function with 2-color functionality
|
||||||
|
|
||||||
# Open test image (256px by 10px, black to white)
|
# Open test image (256px by 10px, black to white)
|
||||||
im = Image.open("Tests/images/bw_gradient.png")
|
im = Image.open("Tests/images/bw_gradient.png")
|
||||||
im = im.convert("L")
|
im = im.convert("L")
|
||||||
|
|
||||||
# Create image with original 2-color functionality
|
# Create image with original 2-color functionality
|
||||||
im_2c = ImageOps.colorize(im, 'red', 'green')
|
im_test = ImageOps.colorize(im, 'red', 'green')
|
||||||
|
|
||||||
# Create image with original 2-color functionality with offsets
|
|
||||||
im_2c_offset = ImageOps.colorize(im,
|
|
||||||
black='red',
|
|
||||||
white='green',
|
|
||||||
blackpoint=50,
|
|
||||||
whitepoint=200)
|
|
||||||
|
|
||||||
# Create image with new three color functionality with offsets
|
|
||||||
im_3c_offset = ImageOps.colorize(im,
|
|
||||||
black='red',
|
|
||||||
white='green',
|
|
||||||
mid='blue',
|
|
||||||
blackpoint=50,
|
|
||||||
whitepoint=200,
|
|
||||||
midpoint=100)
|
|
||||||
|
|
||||||
# Define function for approximate equality of tuples
|
|
||||||
def tuple_approx_equal(actual, target, thresh):
|
|
||||||
value = True
|
|
||||||
for i, target in enumerate(target):
|
|
||||||
value *= (target - thresh <= actual[i] <= target + thresh)
|
|
||||||
return value
|
|
||||||
|
|
||||||
# Test output image (2-color)
|
# Test output image (2-color)
|
||||||
left = (0, 1)
|
left = (0, 1)
|
||||||
middle = (127, 1)
|
middle = (127, 1)
|
||||||
right = (255, 1)
|
right = (255, 1)
|
||||||
self.assertTrue(tuple_approx_equal(im_2c.getpixel(left),
|
self.assertTrue(tuple_approx_equal(im_test.getpixel(left),
|
||||||
(255, 0, 0), thresh=1),
|
(255, 0, 0), threshold=1),
|
||||||
'2-color image black incorrect')
|
'2-color image black incorrect')
|
||||||
self.assertTrue(tuple_approx_equal(im_2c.getpixel(middle),
|
self.assertTrue(tuple_approx_equal(im_test.getpixel(middle),
|
||||||
(127, 63, 0), thresh=1),
|
(127, 63, 0), threshold=1),
|
||||||
'2-color image mid incorrect')
|
'2-color image mid incorrect')
|
||||||
self.assertTrue(tuple_approx_equal(im_2c.getpixel(right),
|
self.assertTrue(tuple_approx_equal(im_test.getpixel(right),
|
||||||
(0, 127, 0), thresh=1),
|
(0, 127, 0), threshold=1),
|
||||||
'2-color image white incorrect')
|
'2-color image white incorrect')
|
||||||
|
|
||||||
|
def test_colorize_2color_offset(self):
|
||||||
|
# Test the colorizing function with 2-color functionality and offset
|
||||||
|
|
||||||
|
# Open test image (256px by 10px, black to white)
|
||||||
|
im = Image.open("Tests/images/bw_gradient.png")
|
||||||
|
im = im.convert("L")
|
||||||
|
|
||||||
|
# Create image with original 2-color functionality with offsets
|
||||||
|
im_test = ImageOps.colorize(im,
|
||||||
|
black='red',
|
||||||
|
white='green',
|
||||||
|
blackpoint=50,
|
||||||
|
whitepoint=100)
|
||||||
|
|
||||||
# Test output image (2-color) with offsets
|
# Test output image (2-color) with offsets
|
||||||
left = (25, 1)
|
left = (25, 1)
|
||||||
middle = (125, 1)
|
middle = (75, 1)
|
||||||
right = (225, 1)
|
right = (125, 1)
|
||||||
self.assertTrue(tuple_approx_equal(im_2c_offset.getpixel(left),
|
self.assertTrue(tuple_approx_equal(im_test.getpixel(left),
|
||||||
(255, 0, 0), thresh=1),
|
(255, 0, 0), threshold=1),
|
||||||
'2-color image (with offset) black incorrect')
|
'2-color image (with offset) black incorrect')
|
||||||
self.assertTrue(tuple_approx_equal(im_2c_offset.getpixel(middle),
|
self.assertTrue(tuple_approx_equal(im_test.getpixel(middle),
|
||||||
(127, 63, 0), thresh=1),
|
(127, 63, 0), threshold=1),
|
||||||
'2-color image (with offset) mid incorrect')
|
'2-color image (with offset) mid incorrect')
|
||||||
self.assertTrue(tuple_approx_equal(im_2c_offset.getpixel(right),
|
self.assertTrue(tuple_approx_equal(im_test.getpixel(right),
|
||||||
(0, 127, 0), thresh=1),
|
(0, 127, 0), threshold=1),
|
||||||
'2-color image (with offset) white incorrect')
|
'2-color image (with offset) white incorrect')
|
||||||
|
|
||||||
|
def test_colorize_3color_offset(self):
|
||||||
|
# Test the colorizing function with 3-color functionality and offset
|
||||||
|
|
||||||
|
# Open test image (256px by 10px, black to white)
|
||||||
|
im = Image.open("Tests/images/bw_gradient.png")
|
||||||
|
im = im.convert("L")
|
||||||
|
|
||||||
|
# Create image with new three color functionality with offsets
|
||||||
|
im_test = ImageOps.colorize(im,
|
||||||
|
black='red',
|
||||||
|
white='green',
|
||||||
|
mid='blue',
|
||||||
|
blackpoint=50,
|
||||||
|
whitepoint=200,
|
||||||
|
midpoint=100)
|
||||||
|
|
||||||
# Test output image (3-color) with offsets
|
# Test output image (3-color) with offsets
|
||||||
left = (25, 1)
|
left = (25, 1)
|
||||||
left_middle = (75, 1)
|
left_middle = (75, 1)
|
||||||
middle = (100, 1)
|
middle = (100, 1)
|
||||||
right_middle = (150, 1)
|
right_middle = (150, 1)
|
||||||
right = (225, 1)
|
right = (225, 1)
|
||||||
self.assertTrue(tuple_approx_equal(im_3c_offset.getpixel(left),
|
self.assertTrue(tuple_approx_equal(im_test.getpixel(left),
|
||||||
(255, 0, 0), thresh=1),
|
(255, 0, 0), threshold=1),
|
||||||
'3-color image (with offset) black incorrect')
|
'3-color image (with offset) black incorrect')
|
||||||
self.assertTrue(tuple_approx_equal(im_3c_offset.getpixel(left_middle),
|
self.assertTrue(tuple_approx_equal(im_test.getpixel(left_middle),
|
||||||
(127, 0, 127), thresh=1),
|
(127, 0, 127), threshold=1),
|
||||||
'3-color image (with offset) low-mid incorrect')
|
'3-color image (with offset) low-mid incorrect')
|
||||||
self.assertTrue(tuple_approx_equal(im_3c_offset.getpixel(middle),
|
self.assertTrue(tuple_approx_equal(im_test.getpixel(middle),
|
||||||
(0, 0, 255), thresh=1),
|
(0, 0, 255), threshold=1),
|
||||||
'3-color image (with offset) mid incorrect')
|
'3-color image (with offset) mid incorrect')
|
||||||
self.assertTrue(tuple_approx_equal(im_3c_offset.getpixel(right_middle),
|
self.assertTrue(tuple_approx_equal(im_test.getpixel(right_middle),
|
||||||
(0, 63, 127), thresh=1),
|
(0, 63, 127), threshold=1),
|
||||||
'3-color image (with offset) high-mid incorrect')
|
'3-color image (with offset) high-mid incorrect')
|
||||||
self.assertTrue(tuple_approx_equal(im_3c_offset.getpixel(right),
|
self.assertTrue(tuple_approx_equal(im_test.getpixel(right),
|
||||||
(0, 127, 0), thresh=1),
|
(0, 127, 0), threshold=1),
|
||||||
'3-color image (with offset) white incorrect')
|
'3-color image (with offset) white incorrect')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -162,13 +162,10 @@ def colorize(image, black, white, mid=None, blackpoint=0,
|
||||||
|
|
||||||
# Initial asserts
|
# Initial asserts
|
||||||
assert image.mode == "L"
|
assert image.mode == "L"
|
||||||
assert 0 <= whitepoint <= 255
|
if mid is None:
|
||||||
assert 0 <= blackpoint <= 255
|
assert 0 <= blackpoint <= whitepoint <= 255
|
||||||
assert 0 <= midpoint <= 255
|
else:
|
||||||
assert blackpoint <= whitepoint
|
assert 0 <= blackpoint <= midpoint <= whitepoint <= 255
|
||||||
if mid is not None:
|
|
||||||
assert blackpoint <= midpoint
|
|
||||||
assert whitepoint >= midpoint
|
|
||||||
|
|
||||||
# Define colors from arguments
|
# Define colors from arguments
|
||||||
black = _color(black, "RGB")
|
black = _color(black, "RGB")
|
||||||
|
@ -181,42 +178,28 @@ def colorize(image, black, white, mid=None, blackpoint=0,
|
||||||
green = []
|
green = []
|
||||||
blue = []
|
blue = []
|
||||||
|
|
||||||
|
# Create the low-end values
|
||||||
|
for i in range(0, blackpoint):
|
||||||
|
red.append(black[0])
|
||||||
|
green.append(black[1])
|
||||||
|
blue.append(black[2])
|
||||||
|
|
||||||
# Create the mapping (2-color)
|
# Create the mapping (2-color)
|
||||||
if mid is None:
|
if mid is None:
|
||||||
|
|
||||||
# Define ranges
|
|
||||||
range_low = range(0, blackpoint)
|
|
||||||
range_map = range(0, whitepoint - blackpoint)
|
range_map = range(0, whitepoint - blackpoint)
|
||||||
range_high = range(0, 256 - whitepoint)
|
|
||||||
|
|
||||||
# Map
|
|
||||||
for i in range_low:
|
|
||||||
red.append(black[0])
|
|
||||||
green.append(black[1])
|
|
||||||
blue.append(black[2])
|
|
||||||
for i in range_map:
|
for i in range_map:
|
||||||
red.append(black[0] + i * (white[0] - black[0]) // len(range_map))
|
red.append(black[0] + i * (white[0] - black[0]) // len(range_map))
|
||||||
green.append(black[1] + i * (white[1] - black[1]) // len(range_map))
|
green.append(black[1] + i * (white[1] - black[1]) // len(range_map))
|
||||||
blue.append(black[2] + i * (white[2] - black[2]) // len(range_map))
|
blue.append(black[2] + i * (white[2] - black[2]) // len(range_map))
|
||||||
for i in range_high:
|
|
||||||
red.append(white[0])
|
|
||||||
green.append(white[1])
|
|
||||||
blue.append(white[2])
|
|
||||||
|
|
||||||
# Create the mapping (3-color)
|
# Create the mapping (3-color)
|
||||||
else:
|
else:
|
||||||
|
|
||||||
# Define ranges
|
|
||||||
range_low = range(0, blackpoint)
|
|
||||||
range_map1 = range(0, midpoint - blackpoint)
|
range_map1 = range(0, midpoint - blackpoint)
|
||||||
range_map2 = range(0, whitepoint - midpoint)
|
range_map2 = range(0, whitepoint - midpoint)
|
||||||
range_high = range(0, 256 - whitepoint)
|
|
||||||
|
|
||||||
# Map
|
|
||||||
for i in range_low:
|
|
||||||
red.append(black[0])
|
|
||||||
green.append(black[1])
|
|
||||||
blue.append(black[2])
|
|
||||||
for i in range_map1:
|
for i in range_map1:
|
||||||
red.append(black[0] + i * (mid[0] - black[0]) // len(range_map1))
|
red.append(black[0] + i * (mid[0] - black[0]) // len(range_map1))
|
||||||
green.append(black[1] + i * (mid[1] - black[1]) // len(range_map1))
|
green.append(black[1] + i * (mid[1] - black[1]) // len(range_map1))
|
||||||
|
@ -225,10 +208,12 @@ def colorize(image, black, white, mid=None, blackpoint=0,
|
||||||
red.append(mid[0] + i * (white[0] - mid[0]) // len(range_map2))
|
red.append(mid[0] + i * (white[0] - mid[0]) // len(range_map2))
|
||||||
green.append(mid[1] + i * (white[1] - mid[1]) // len(range_map2))
|
green.append(mid[1] + i * (white[1] - mid[1]) // len(range_map2))
|
||||||
blue.append(mid[2] + i * (white[2] - mid[2]) // len(range_map2))
|
blue.append(mid[2] + i * (white[2] - mid[2]) // len(range_map2))
|
||||||
for i in range_high:
|
|
||||||
red.append(white[0])
|
# Create the high-end values
|
||||||
green.append(white[1])
|
for i in range(0, 256 - whitepoint):
|
||||||
blue.append(white[2])
|
red.append(white[0])
|
||||||
|
green.append(white[1])
|
||||||
|
blue.append(white[2])
|
||||||
|
|
||||||
# Return converted image
|
# Return converted image
|
||||||
image = image.convert("RGB")
|
image = image.convert("RGB")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user