2015-08-05 17:23:14 +03:00
|
|
|
from PIL import Image
|
2014-06-10 13:10:47 +04:00
|
|
|
|
2019-07-06 23:40:53 +03:00
|
|
|
from .helper import PillowTestCase, hopper
|
|
|
|
|
2014-06-10 13:10:47 +04:00
|
|
|
|
|
|
|
class TestImageRotate(PillowTestCase):
|
2016-12-31 22:12:39 +03:00
|
|
|
def rotate(self, im, mode, angle, center=None, translate=None):
|
|
|
|
out = im.rotate(angle, center=center, translate=translate)
|
|
|
|
self.assertEqual(out.mode, mode)
|
|
|
|
self.assertEqual(out.size, im.size) # default rotate clips output
|
|
|
|
out = im.rotate(angle, center=center, translate=translate, expand=1)
|
|
|
|
self.assertEqual(out.mode, mode)
|
|
|
|
if angle % 180 == 0:
|
|
|
|
self.assertEqual(out.size, im.size)
|
|
|
|
elif im.size == (0, 0):
|
|
|
|
self.assertEqual(out.size, im.size)
|
|
|
|
else:
|
|
|
|
self.assertNotEqual(out.size, im.size)
|
|
|
|
|
2017-04-20 14:14:23 +03:00
|
|
|
def test_mode(self):
|
2016-12-31 16:08:00 +03:00
|
|
|
for mode in ("1", "P", "L", "RGB", "I", "F"):
|
2015-08-05 17:23:14 +03:00
|
|
|
im = hopper(mode)
|
2016-12-31 22:12:39 +03:00
|
|
|
self.rotate(im, mode, 45)
|
2016-12-31 16:08:00 +03:00
|
|
|
|
2016-12-31 22:12:39 +03:00
|
|
|
def test_angle(self):
|
2016-12-31 16:08:00 +03:00
|
|
|
for angle in (0, 90, 180, 270):
|
2019-11-25 23:03:23 +03:00
|
|
|
with Image.open("Tests/images/test-card.png") as im:
|
|
|
|
self.rotate(im, im.mode, angle)
|
2014-06-10 13:10:47 +04:00
|
|
|
|
2016-12-31 22:12:39 +03:00
|
|
|
def test_zero(self):
|
2016-12-31 16:08:00 +03:00
|
|
|
for angle in (0, 45, 90, 180, 270):
|
2019-06-13 18:54:24 +03:00
|
|
|
im = Image.new("RGB", (0, 0))
|
2016-12-31 22:12:39 +03:00
|
|
|
self.rotate(im, im.mode, angle)
|
2016-12-31 16:08:00 +03:00
|
|
|
|
2016-12-31 22:30:26 +03:00
|
|
|
def test_resample(self):
|
2017-04-20 14:14:23 +03:00
|
|
|
# Target image creation, inspected by eye.
|
2016-12-31 22:30:26 +03:00
|
|
|
# >>> im = Image.open('Tests/images/hopper.ppm')
|
2017-04-20 14:14:23 +03:00
|
|
|
# >>> im = im.rotate(45, resample=Image.BICUBIC, expand=True)
|
2016-12-31 22:30:26 +03:00
|
|
|
# >>> im.save('Tests/images/hopper_45.png')
|
|
|
|
|
2019-11-25 23:03:23 +03:00
|
|
|
with Image.open("Tests/images/hopper_45.png") as target:
|
|
|
|
for (resample, epsilon) in (
|
|
|
|
(Image.NEAREST, 10),
|
|
|
|
(Image.BILINEAR, 5),
|
|
|
|
(Image.BICUBIC, 0),
|
|
|
|
):
|
|
|
|
im = hopper()
|
|
|
|
im = im.rotate(45, resample=resample, expand=True)
|
|
|
|
self.assert_image_similar(im, target, epsilon)
|
2016-12-31 22:30:26 +03:00
|
|
|
|
2017-01-01 14:09:06 +03:00
|
|
|
def test_center_0(self):
|
|
|
|
im = hopper()
|
2017-04-20 14:14:23 +03:00
|
|
|
im = im.rotate(45, center=(0, 0), resample=Image.BICUBIC)
|
2017-01-01 14:09:06 +03:00
|
|
|
|
2019-11-25 23:03:23 +03:00
|
|
|
with Image.open("Tests/images/hopper_45.png") as target:
|
|
|
|
target_origin = target.size[1] / 2
|
|
|
|
target = target.crop((0, target_origin, 128, target_origin + 128))
|
|
|
|
|
2017-01-01 14:09:06 +03:00
|
|
|
self.assert_image_similar(im, target, 15)
|
|
|
|
|
|
|
|
def test_center_14(self):
|
|
|
|
im = hopper()
|
2017-04-20 14:14:23 +03:00
|
|
|
im = im.rotate(45, center=(14, 14), resample=Image.BICUBIC)
|
2017-01-01 14:09:06 +03:00
|
|
|
|
2019-11-25 23:03:23 +03:00
|
|
|
with Image.open("Tests/images/hopper_45.png") as target:
|
|
|
|
target_origin = target.size[1] / 2 - 14
|
|
|
|
target = target.crop((6, target_origin, 128 + 6, target_origin + 128))
|
|
|
|
|
|
|
|
self.assert_image_similar(im, target, 10)
|
2017-01-01 14:09:06 +03:00
|
|
|
|
|
|
|
def test_translate(self):
|
|
|
|
im = hopper()
|
2019-11-25 23:03:23 +03:00
|
|
|
with Image.open("Tests/images/hopper_45.png") as target:
|
|
|
|
target_origin = (target.size[1] / 2 - 64) - 5
|
|
|
|
target = target.crop(
|
|
|
|
(target_origin, target_origin, target_origin + 128, target_origin + 128)
|
|
|
|
)
|
2017-01-01 14:09:06 +03:00
|
|
|
|
2017-04-20 14:14:23 +03:00
|
|
|
im = im.rotate(45, translate=(5, 5), resample=Image.BICUBIC)
|
2017-01-01 14:09:06 +03:00
|
|
|
|
|
|
|
self.assert_image_similar(im, target, 1)
|
|
|
|
|
|
|
|
def test_fastpath_center(self):
|
|
|
|
# if the center is -1,-1 and we rotate by 90<=x<=270 the
|
|
|
|
# resulting image should be black
|
|
|
|
for angle in (90, 180, 270):
|
2017-04-20 14:14:23 +03:00
|
|
|
im = hopper().rotate(angle, center=(-1, -1))
|
2019-06-13 18:54:24 +03:00
|
|
|
self.assert_image_equal(im, Image.new("RGB", im.size, "black"))
|
2017-01-01 14:09:06 +03:00
|
|
|
|
|
|
|
def test_fastpath_translate(self):
|
|
|
|
# if we post-translate by -128
|
|
|
|
# resulting image should be black
|
|
|
|
for angle in (0, 90, 180, 270):
|
2017-04-20 14:14:23 +03:00
|
|
|
im = hopper().rotate(angle, translate=(-128, -128))
|
2019-06-13 18:54:24 +03:00
|
|
|
self.assert_image_equal(im, Image.new("RGB", im.size, "black"))
|
2017-01-01 14:09:06 +03:00
|
|
|
|
2016-12-31 22:12:39 +03:00
|
|
|
def test_center(self):
|
|
|
|
im = hopper()
|
|
|
|
self.rotate(im, im.mode, 45, center=(0, 0))
|
2019-06-13 18:54:24 +03:00
|
|
|
self.rotate(im, im.mode, 45, translate=(im.size[0] / 2, 0))
|
|
|
|
self.rotate(im, im.mode, 45, center=(0, 0), translate=(im.size[0] / 2, 0))
|
2018-06-24 15:32:25 +03:00
|
|
|
|
2018-03-27 17:18:35 +03:00
|
|
|
def test_rotate_no_fill(self):
|
2019-06-13 18:54:24 +03:00
|
|
|
im = Image.new("RGB", (100, 100), "green")
|
2018-03-27 17:18:35 +03:00
|
|
|
im = im.rotate(45)
|
2019-11-25 23:03:23 +03:00
|
|
|
with Image.open("Tests/images/rotate_45_no_fill.png") as target:
|
|
|
|
self.assert_image_equal(im, target)
|
2018-03-27 17:18:35 +03:00
|
|
|
|
2018-03-27 16:11:49 +03:00
|
|
|
def test_rotate_with_fill(self):
|
2019-06-13 18:54:24 +03:00
|
|
|
im = Image.new("RGB", (100, 100), "green")
|
|
|
|
im = im.rotate(45, fillcolor="white")
|
2019-11-25 23:03:23 +03:00
|
|
|
with Image.open("Tests/images/rotate_45_with_fill.png") as target:
|
|
|
|
self.assert_image_equal(im, target)
|
2016-12-31 22:12:39 +03:00
|
|
|
|
2018-05-30 17:05:58 +03:00
|
|
|
def test_alpha_rotate_no_fill(self):
|
|
|
|
# Alpha images are handled differently internally
|
2019-06-13 18:54:24 +03:00
|
|
|
im = Image.new("RGBA", (10, 10), "green")
|
2018-05-30 17:05:58 +03:00
|
|
|
im = im.rotate(45, expand=1)
|
2018-09-27 12:43:39 +03:00
|
|
|
corner = im.getpixel((0, 0))
|
2018-05-30 17:05:58 +03:00
|
|
|
self.assertEqual(corner, (0, 0, 0, 0))
|
|
|
|
|
|
|
|
def test_alpha_rotate_with_fill(self):
|
|
|
|
# Alpha images are handled differently internally
|
2019-06-13 18:54:24 +03:00
|
|
|
im = Image.new("RGBA", (10, 10), "green")
|
2018-05-30 17:05:58 +03:00
|
|
|
im = im.rotate(45, expand=1, fillcolor=(255, 0, 0, 255))
|
2018-09-27 12:43:39 +03:00
|
|
|
corner = im.getpixel((0, 0))
|
2018-05-30 17:05:58 +03:00
|
|
|
self.assertEqual(corner, (255, 0, 0, 255))
|