2018-07-09 17:04:48 +03:00
|
|
|
from helper import unittest, PillowTestCase, hopper
|
2012-10-16 00:26:38 +04:00
|
|
|
|
|
|
|
from PIL import ImageOps
|
2018-07-07 12:40:25 +03:00
|
|
|
from PIL import Image
|
2012-10-16 00:26:38 +04:00
|
|
|
|
|
|
|
|
2014-06-10 13:10:47 +04:00
|
|
|
class TestImageOps(PillowTestCase):
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2015-05-26 17:07:21 +03:00
|
|
|
class Deformer(object):
|
2014-06-10 13:10:47 +04:00
|
|
|
def getmesh(self, im):
|
|
|
|
x, y = im.size
|
|
|
|
return [((0, 0, x, y), (0, 0, x, 0, x, y, y, 0))]
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2014-06-10 13:10:47 +04:00
|
|
|
deformer = Deformer()
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2014-06-10 13:10:47 +04:00
|
|
|
def test_sanity(self):
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2014-09-05 14:03:56 +04:00
|
|
|
ImageOps.autocontrast(hopper("L"))
|
|
|
|
ImageOps.autocontrast(hopper("RGB"))
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2014-09-05 14:03:56 +04:00
|
|
|
ImageOps.autocontrast(hopper("L"), cutoff=10)
|
|
|
|
ImageOps.autocontrast(hopper("L"), ignore=[0, 255])
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2014-09-05 14:03:56 +04:00
|
|
|
ImageOps.colorize(hopper("L"), (0, 0, 0), (255, 255, 255))
|
|
|
|
ImageOps.colorize(hopper("L"), "black", "white")
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2018-09-26 13:07:46 +03:00
|
|
|
ImageOps.pad(hopper("L"), (128, 128))
|
|
|
|
ImageOps.pad(hopper("RGB"), (128, 128))
|
|
|
|
|
2014-09-05 14:03:56 +04:00
|
|
|
ImageOps.crop(hopper("L"), 1)
|
|
|
|
ImageOps.crop(hopper("RGB"), 1)
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2014-09-05 14:03:56 +04:00
|
|
|
ImageOps.deform(hopper("L"), self.deformer)
|
|
|
|
ImageOps.deform(hopper("RGB"), self.deformer)
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2014-09-05 14:03:56 +04:00
|
|
|
ImageOps.equalize(hopper("L"))
|
|
|
|
ImageOps.equalize(hopper("RGB"))
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2014-09-05 14:03:56 +04:00
|
|
|
ImageOps.expand(hopper("L"), 1)
|
|
|
|
ImageOps.expand(hopper("RGB"), 1)
|
|
|
|
ImageOps.expand(hopper("L"), 2, "blue")
|
|
|
|
ImageOps.expand(hopper("RGB"), 2, "blue")
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2014-09-05 14:03:56 +04:00
|
|
|
ImageOps.fit(hopper("L"), (128, 128))
|
|
|
|
ImageOps.fit(hopper("RGB"), (128, 128))
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2014-09-05 14:03:56 +04:00
|
|
|
ImageOps.flip(hopper("L"))
|
|
|
|
ImageOps.flip(hopper("RGB"))
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2014-09-05 14:03:56 +04:00
|
|
|
ImageOps.grayscale(hopper("L"))
|
|
|
|
ImageOps.grayscale(hopper("RGB"))
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2014-09-05 14:03:56 +04:00
|
|
|
ImageOps.invert(hopper("L"))
|
|
|
|
ImageOps.invert(hopper("RGB"))
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2014-09-05 14:03:56 +04:00
|
|
|
ImageOps.mirror(hopper("L"))
|
|
|
|
ImageOps.mirror(hopper("RGB"))
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2014-09-05 14:03:56 +04:00
|
|
|
ImageOps.posterize(hopper("L"), 4)
|
|
|
|
ImageOps.posterize(hopper("RGB"), 4)
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2014-09-05 14:03:56 +04:00
|
|
|
ImageOps.solarize(hopper("L"))
|
|
|
|
ImageOps.solarize(hopper("RGB"))
|
2013-07-01 15:36:46 +04:00
|
|
|
|
2014-06-10 13:10:47 +04:00
|
|
|
def test_1pxfit(self):
|
|
|
|
# Division by zero in equalize if image is 1 pixel high
|
2014-09-05 14:03:56 +04:00
|
|
|
newimg = ImageOps.fit(hopper("RGB").resize((1, 1)), (35, 35))
|
2014-06-10 13:10:47 +04:00
|
|
|
self.assertEqual(newimg.size, (35, 35))
|
2013-07-01 15:36:46 +04:00
|
|
|
|
2014-09-05 14:03:56 +04:00
|
|
|
newimg = ImageOps.fit(hopper("RGB").resize((1, 100)), (35, 35))
|
2014-06-10 13:10:47 +04:00
|
|
|
self.assertEqual(newimg.size, (35, 35))
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2014-09-05 14:03:56 +04:00
|
|
|
newimg = ImageOps.fit(hopper("RGB").resize((100, 1)), (35, 35))
|
2014-06-10 13:10:47 +04:00
|
|
|
self.assertEqual(newimg.size, (35, 35))
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2018-09-26 13:07:46 +03:00
|
|
|
def test_pad(self):
|
|
|
|
# Same ratio
|
|
|
|
im = hopper()
|
|
|
|
new_size = (im.width * 2, im.height * 2)
|
|
|
|
new_im = ImageOps.pad(im, new_size)
|
|
|
|
self.assertEqual(new_im.size, new_size)
|
|
|
|
|
|
|
|
for label, color, new_size in [
|
|
|
|
("h", None, (im.width * 4, im.height * 2)),
|
|
|
|
("v", "#f00", (im.width * 2, im.height * 4))
|
|
|
|
]:
|
2018-09-27 12:43:39 +03:00
|
|
|
for i, centering in enumerate([(0, 0), (0.5, 0.5), (1, 1)]):
|
2018-09-26 13:07:46 +03:00
|
|
|
new_im = ImageOps.pad(im, new_size,
|
|
|
|
color=color, centering=centering)
|
|
|
|
self.assertEqual(new_im.size, new_size)
|
|
|
|
|
|
|
|
target = Image.open(
|
|
|
|
"Tests/images/imageops_pad_"+label+"_"+str(i)+".jpg")
|
|
|
|
self.assert_image_similar(new_im, target, 6)
|
|
|
|
|
2014-06-10 13:10:47 +04:00
|
|
|
def test_pil163(self):
|
|
|
|
# Division by zero in equalize if < 255 pixels in image (@PIL163)
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2014-09-05 14:03:56 +04:00
|
|
|
i = hopper("RGB").resize((15, 16))
|
2014-06-10 13:10:47 +04:00
|
|
|
|
|
|
|
ImageOps.equalize(i.convert("L"))
|
|
|
|
ImageOps.equalize(i.convert("P"))
|
|
|
|
ImageOps.equalize(i.convert("RGB"))
|
|
|
|
|
2016-07-05 21:15:14 +03:00
|
|
|
def test_scale(self):
|
|
|
|
# Test the scaling function
|
2016-07-06 02:32:16 +03:00
|
|
|
i = hopper("L").resize((50, 50))
|
2016-09-03 05:23:42 +03:00
|
|
|
|
2016-07-05 21:46:47 +03:00
|
|
|
with self.assertRaises(ValueError):
|
2016-07-06 11:21:00 +03:00
|
|
|
ImageOps.scale(i, -1)
|
2016-07-05 21:46:47 +03:00
|
|
|
|
2016-07-06 11:21:00 +03:00
|
|
|
newimg = ImageOps.scale(i, 1)
|
2016-07-05 21:46:47 +03:00
|
|
|
self.assertEqual(newimg.size, (50, 50))
|
|
|
|
|
2016-07-06 11:21:00 +03:00
|
|
|
newimg = ImageOps.scale(i, 2)
|
2016-07-05 21:15:14 +03:00
|
|
|
self.assertEqual(newimg.size, (100, 100))
|
|
|
|
|
2016-07-06 11:21:00 +03:00
|
|
|
newimg = ImageOps.scale(i, 0.5)
|
2016-07-05 21:15:14 +03:00
|
|
|
self.assertEqual(newimg.size, (25, 25))
|
|
|
|
|
2018-07-09 06:09:39 +03:00
|
|
|
def test_colorize_2color(self):
|
|
|
|
# Test the colorizing function with 2-color functionality
|
2018-07-07 04:42:16 +03:00
|
|
|
|
2018-07-08 04:19:26 +03:00
|
|
|
# Open test image (256px by 10px, black to white)
|
2018-07-07 12:40:25 +03:00
|
|
|
im = Image.open("Tests/images/bw_gradient.png")
|
|
|
|
im = im.convert("L")
|
2018-07-07 04:42:16 +03:00
|
|
|
|
2018-07-08 04:19:26 +03:00
|
|
|
# Create image with original 2-color functionality
|
2018-07-09 06:09:39 +03:00
|
|
|
im_test = ImageOps.colorize(im, 'red', 'green')
|
2018-07-08 04:19:26 +03:00
|
|
|
|
|
|
|
# Test output image (2-color)
|
|
|
|
left = (0, 1)
|
|
|
|
middle = (127, 1)
|
|
|
|
right = (255, 1)
|
2018-07-09 17:04:48 +03:00
|
|
|
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')
|
2018-07-08 04:19:26 +03:00
|
|
|
|
2018-07-09 06:09:39 +03:00
|
|
|
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)
|
|
|
|
|
2018-07-08 04:19:26 +03:00
|
|
|
# Test output image (2-color) with offsets
|
|
|
|
left = (25, 1)
|
2018-07-09 06:09:39 +03:00
|
|
|
middle = (75, 1)
|
|
|
|
right = (125, 1)
|
2018-07-09 17:04:48 +03:00
|
|
|
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')
|
2018-07-08 04:19:26 +03:00
|
|
|
|
2018-07-09 06:09:39 +03:00
|
|
|
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)
|
|
|
|
|
2018-07-08 04:19:26 +03:00
|
|
|
# Test output image (3-color) with offsets
|
|
|
|
left = (25, 1)
|
|
|
|
left_middle = (75, 1)
|
|
|
|
middle = (100, 1)
|
|
|
|
right_middle = (150, 1)
|
|
|
|
right = (225, 1)
|
2018-07-09 17:04:48 +03:00
|
|
|
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')
|
2018-07-07 04:42:16 +03:00
|
|
|
|
2014-06-10 13:10:47 +04:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
unittest.main()
|