mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-25 17:36:18 +03:00
d50445ff30
Similar to the recent adoption of Black. isort is a Python utility to sort imports alphabetically and automatically separate into sections. By using isort, contributors can quickly and automatically conform to the projects style without thinking. Just let the tool do it. Uses the configuration recommended by the Black to avoid conflicts of style. Rewrite TestImageQt.test_deprecated to no rely on import order.
278 lines
8.9 KiB
Python
278 lines
8.9 KiB
Python
from PIL import Image, ImageOps
|
|
|
|
from .helper import PillowTestCase, hopper
|
|
|
|
try:
|
|
from PIL import _webp
|
|
|
|
HAVE_WEBP = True
|
|
except ImportError:
|
|
HAVE_WEBP = False
|
|
|
|
|
|
class TestImageOps(PillowTestCase):
|
|
class Deformer(object):
|
|
def getmesh(self, im):
|
|
x, y = im.size
|
|
return [((0, 0, x, y), (0, 0, x, 0, x, y, y, 0))]
|
|
|
|
deformer = Deformer()
|
|
|
|
def test_sanity(self):
|
|
|
|
ImageOps.autocontrast(hopper("L"))
|
|
ImageOps.autocontrast(hopper("RGB"))
|
|
|
|
ImageOps.autocontrast(hopper("L"), cutoff=10)
|
|
ImageOps.autocontrast(hopper("L"), ignore=[0, 255])
|
|
|
|
ImageOps.colorize(hopper("L"), (0, 0, 0), (255, 255, 255))
|
|
ImageOps.colorize(hopper("L"), "black", "white")
|
|
|
|
ImageOps.pad(hopper("L"), (128, 128))
|
|
ImageOps.pad(hopper("RGB"), (128, 128))
|
|
|
|
ImageOps.crop(hopper("L"), 1)
|
|
ImageOps.crop(hopper("RGB"), 1)
|
|
|
|
ImageOps.deform(hopper("L"), self.deformer)
|
|
ImageOps.deform(hopper("RGB"), self.deformer)
|
|
|
|
ImageOps.equalize(hopper("L"))
|
|
ImageOps.equalize(hopper("RGB"))
|
|
|
|
ImageOps.expand(hopper("L"), 1)
|
|
ImageOps.expand(hopper("RGB"), 1)
|
|
ImageOps.expand(hopper("L"), 2, "blue")
|
|
ImageOps.expand(hopper("RGB"), 2, "blue")
|
|
|
|
ImageOps.fit(hopper("L"), (128, 128))
|
|
ImageOps.fit(hopper("RGB"), (128, 128))
|
|
|
|
ImageOps.flip(hopper("L"))
|
|
ImageOps.flip(hopper("RGB"))
|
|
|
|
ImageOps.grayscale(hopper("L"))
|
|
ImageOps.grayscale(hopper("RGB"))
|
|
|
|
ImageOps.invert(hopper("L"))
|
|
ImageOps.invert(hopper("RGB"))
|
|
|
|
ImageOps.mirror(hopper("L"))
|
|
ImageOps.mirror(hopper("RGB"))
|
|
|
|
ImageOps.posterize(hopper("L"), 4)
|
|
ImageOps.posterize(hopper("RGB"), 4)
|
|
|
|
ImageOps.solarize(hopper("L"))
|
|
ImageOps.solarize(hopper("RGB"))
|
|
|
|
ImageOps.exif_transpose(hopper("L"))
|
|
ImageOps.exif_transpose(hopper("RGB"))
|
|
|
|
def test_1pxfit(self):
|
|
# Division by zero in equalize if image is 1 pixel high
|
|
newimg = ImageOps.fit(hopper("RGB").resize((1, 1)), (35, 35))
|
|
self.assertEqual(newimg.size, (35, 35))
|
|
|
|
newimg = ImageOps.fit(hopper("RGB").resize((1, 100)), (35, 35))
|
|
self.assertEqual(newimg.size, (35, 35))
|
|
|
|
newimg = ImageOps.fit(hopper("RGB").resize((100, 1)), (35, 35))
|
|
self.assertEqual(newimg.size, (35, 35))
|
|
|
|
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)),
|
|
]:
|
|
for i, centering in enumerate([(0, 0), (0.5, 0.5), (1, 1)]):
|
|
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)
|
|
|
|
def test_pil163(self):
|
|
# Division by zero in equalize if < 255 pixels in image (@PIL163)
|
|
|
|
i = hopper("RGB").resize((15, 16))
|
|
|
|
ImageOps.equalize(i.convert("L"))
|
|
ImageOps.equalize(i.convert("P"))
|
|
ImageOps.equalize(i.convert("RGB"))
|
|
|
|
def test_scale(self):
|
|
# Test the scaling function
|
|
i = hopper("L").resize((50, 50))
|
|
|
|
with self.assertRaises(ValueError):
|
|
ImageOps.scale(i, -1)
|
|
|
|
newimg = ImageOps.scale(i, 1)
|
|
self.assertEqual(newimg.size, (50, 50))
|
|
|
|
newimg = ImageOps.scale(i, 2)
|
|
self.assertEqual(newimg.size, (100, 100))
|
|
|
|
newimg = ImageOps.scale(i, 0.5)
|
|
self.assertEqual(newimg.size, (25, 25))
|
|
|
|
def test_colorize_2color(self):
|
|
# Test the colorizing function with 2-color functionality
|
|
|
|
# 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
|
|
im_test = ImageOps.colorize(im, "red", "green")
|
|
|
|
# Test output image (2-color)
|
|
left = (0, 1)
|
|
middle = (127, 1)
|
|
right = (255, 1)
|
|
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
|
|
|
|
# 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
|
|
left = (25, 1)
|
|
middle = (75, 1)
|
|
right = (125, 1)
|
|
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
|
|
|
|
# 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
|
|
left = (25, 1)
|
|
left_middle = (75, 1)
|
|
middle = (100, 1)
|
|
right_middle = (150, 1)
|
|
right = (225, 1)
|
|
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",
|
|
)
|
|
|
|
def test_exif_transpose(self):
|
|
exts = [".jpg"]
|
|
if HAVE_WEBP and _webp.HAVE_WEBPANIM:
|
|
exts.append(".webp")
|
|
for ext in exts:
|
|
base_im = Image.open("Tests/images/hopper" + ext)
|
|
|
|
orientations = [base_im]
|
|
for i in range(2, 9):
|
|
im = Image.open("Tests/images/hopper_orientation_" + str(i) + ext)
|
|
orientations.append(im)
|
|
for i, orientation_im in enumerate(orientations):
|
|
for im in [orientation_im, orientation_im.copy()]: # ImageFile # Image
|
|
if i == 0:
|
|
self.assertNotIn("exif", im.info)
|
|
else:
|
|
original_exif = im.info["exif"]
|
|
transposed_im = ImageOps.exif_transpose(im)
|
|
self.assert_image_similar(base_im, transposed_im, 17)
|
|
if i == 0:
|
|
self.assertNotIn("exif", im.info)
|
|
else:
|
|
self.assertNotEqual(transposed_im.info["exif"], original_exif)
|
|
|
|
self.assertNotIn(0x0112, transposed_im.getexif())
|
|
|
|
# Repeat the operation, to test that it does not keep transposing
|
|
transposed_im2 = ImageOps.exif_transpose(transposed_im)
|
|
self.assert_image_equal(transposed_im2, transposed_im)
|