mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 01:47:47 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			410 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			410 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from helper import unittest, PillowTestCase, hopper
 | 
						|
 | 
						|
from PIL import Image
 | 
						|
from PIL import ImageColor
 | 
						|
from PIL import ImageDraw
 | 
						|
import os.path
 | 
						|
 | 
						|
BLACK = (0, 0, 0)
 | 
						|
WHITE = (255, 255, 255)
 | 
						|
GRAY = (190, 190, 190)
 | 
						|
DEFAULT_MODE = 'RGB'
 | 
						|
IMAGES_PATH = os.path.join('Tests', 'images', 'imagedraw')
 | 
						|
 | 
						|
import sys
 | 
						|
 | 
						|
# Image size
 | 
						|
W, H = 100, 100
 | 
						|
 | 
						|
# Bounding box points
 | 
						|
X0 = int(W / 4)
 | 
						|
X1 = int(X0 * 3)
 | 
						|
Y0 = int(H / 4)
 | 
						|
Y1 = int(X0 * 3)
 | 
						|
 | 
						|
# Two kinds of bounding box
 | 
						|
BBOX1 = [(X0, Y0), (X1, Y1)]
 | 
						|
BBOX2 = [X0, Y0, X1, Y1]
 | 
						|
 | 
						|
# Two kinds of coordinate sequences
 | 
						|
POINTS1 = [(10, 10), (20, 40), (30, 30)]
 | 
						|
POINTS2 = [10, 10, 20, 40, 30, 30]
 | 
						|
 | 
						|
 | 
						|
class TestImageDraw(PillowTestCase):
 | 
						|
 | 
						|
    def test_sanity(self):
 | 
						|
        im = hopper("RGB").copy()
 | 
						|
 | 
						|
        draw = ImageDraw.ImageDraw(im)
 | 
						|
        draw = ImageDraw.Draw(im)
 | 
						|
 | 
						|
        draw.ellipse(list(range(4)))
 | 
						|
        draw.line(list(range(10)))
 | 
						|
        draw.polygon(list(range(100)))
 | 
						|
        draw.rectangle(list(range(4)))
 | 
						|
 | 
						|
    def test_deprecated(self):
 | 
						|
        im = hopper().copy()
 | 
						|
 | 
						|
        draw = ImageDraw.Draw(im)
 | 
						|
 | 
						|
        self.assert_warning(DeprecationWarning, lambda: draw.setink(0))
 | 
						|
        self.assert_warning(DeprecationWarning, lambda: draw.setfill(0))
 | 
						|
 | 
						|
    def helper_arc(self, bbox):
 | 
						|
        # Arrange
 | 
						|
        im = Image.new("RGB", (W, H))
 | 
						|
        draw = ImageDraw.Draw(im)
 | 
						|
 | 
						|
        # Act
 | 
						|
        # FIXME Fill param should be named outline.
 | 
						|
        draw.arc(bbox, 0, 180)
 | 
						|
        del draw
 | 
						|
 | 
						|
        # Assert
 | 
						|
        self.assert_image_similar(
 | 
						|
            im, Image.open("Tests/images/imagedraw_arc.png"),1)
 | 
						|
 | 
						|
    def test_arc1(self):
 | 
						|
        self.helper_arc(BBOX1)
 | 
						|
 | 
						|
    def test_arc2(self):
 | 
						|
        self.helper_arc(BBOX2)
 | 
						|
 | 
						|
    def test_bitmap(self):
 | 
						|
        # Arrange
 | 
						|
        small = Image.open("Tests/images/pil123rgba.png").resize((50, 50))
 | 
						|
        im = Image.new("RGB", (W, H))
 | 
						|
        draw = ImageDraw.Draw(im)
 | 
						|
 | 
						|
        # Act
 | 
						|
        draw.bitmap((10, 10), small)
 | 
						|
        del draw
 | 
						|
 | 
						|
        # Assert
 | 
						|
        self.assert_image_equal(
 | 
						|
            im, Image.open("Tests/images/imagedraw_bitmap.png"))
 | 
						|
 | 
						|
    def helper_chord(self, bbox):
 | 
						|
        # Arrange
 | 
						|
        im = Image.new("RGB", (W, H))
 | 
						|
        draw = ImageDraw.Draw(im)
 | 
						|
 | 
						|
        # Act
 | 
						|
        draw.chord(bbox, 0, 180, fill="red", outline="yellow")
 | 
						|
        del draw
 | 
						|
 | 
						|
        # Assert
 | 
						|
        self.assert_image_similar(
 | 
						|
            im, Image.open("Tests/images/imagedraw_chord.png"),1)
 | 
						|
 | 
						|
    def test_chord1(self):
 | 
						|
        self.helper_chord(BBOX1)
 | 
						|
 | 
						|
    def test_chord2(self):
 | 
						|
        self.helper_chord(BBOX2)
 | 
						|
 | 
						|
    def helper_ellipse(self, bbox):
 | 
						|
        # Arrange
 | 
						|
        im = Image.new("RGB", (W, H))
 | 
						|
        draw = ImageDraw.Draw(im)
 | 
						|
 | 
						|
        # Act
 | 
						|
        draw.ellipse(bbox, fill="green", outline="blue")
 | 
						|
        del draw
 | 
						|
 | 
						|
        # Assert
 | 
						|
        self.assert_image_similar(
 | 
						|
            im, Image.open("Tests/images/imagedraw_ellipse.png"),1)
 | 
						|
 | 
						|
    def test_ellipse1(self):
 | 
						|
        self.helper_ellipse(BBOX1)
 | 
						|
 | 
						|
    def test_ellipse2(self):
 | 
						|
        self.helper_ellipse(BBOX2)
 | 
						|
 | 
						|
    def helper_line(self, points):
 | 
						|
        # Arrange
 | 
						|
        im = Image.new("RGB", (W, H))
 | 
						|
        draw = ImageDraw.Draw(im)
 | 
						|
 | 
						|
        # Act
 | 
						|
        draw.line(points, fill="yellow", width=2)
 | 
						|
        del draw
 | 
						|
 | 
						|
        # Assert
 | 
						|
        self.assert_image_equal(
 | 
						|
            im, Image.open("Tests/images/imagedraw_line.png"))
 | 
						|
 | 
						|
    def test_line1(self):
 | 
						|
        self.helper_line(POINTS1)
 | 
						|
 | 
						|
    def test_line2(self):
 | 
						|
        self.helper_line(POINTS2)
 | 
						|
 | 
						|
    def helper_pieslice(self, bbox):
 | 
						|
        # Arrange
 | 
						|
        im = Image.new("RGB", (W, H))
 | 
						|
        draw = ImageDraw.Draw(im)
 | 
						|
 | 
						|
        # Act
 | 
						|
        draw.pieslice(bbox, -90, 45, fill="white", outline="blue")
 | 
						|
        del draw
 | 
						|
 | 
						|
        # Assert
 | 
						|
        self.assert_image_similar(
 | 
						|
            im, Image.open("Tests/images/imagedraw_pieslice.png"),1)
 | 
						|
 | 
						|
    def test_pieslice1(self):
 | 
						|
        self.helper_pieslice(BBOX1)
 | 
						|
 | 
						|
    def test_pieslice2(self):
 | 
						|
        self.helper_pieslice(BBOX2)
 | 
						|
 | 
						|
    def helper_point(self, points):
 | 
						|
        # Arrange
 | 
						|
        im = Image.new("RGB", (W, H))
 | 
						|
        draw = ImageDraw.Draw(im)
 | 
						|
 | 
						|
        # Act
 | 
						|
        draw.point(points, fill="yellow")
 | 
						|
        del draw
 | 
						|
 | 
						|
        # Assert
 | 
						|
        self.assert_image_equal(
 | 
						|
            im, Image.open("Tests/images/imagedraw_point.png"))
 | 
						|
 | 
						|
    def test_point1(self):
 | 
						|
        self.helper_point(POINTS1)
 | 
						|
 | 
						|
    def test_point2(self):
 | 
						|
        self.helper_point(POINTS2)
 | 
						|
 | 
						|
    def helper_polygon(self, points):
 | 
						|
        # Arrange
 | 
						|
        im = Image.new("RGB", (W, H))
 | 
						|
        draw = ImageDraw.Draw(im)
 | 
						|
 | 
						|
        # Act
 | 
						|
        draw.polygon(points, fill="red", outline="blue")
 | 
						|
        del draw
 | 
						|
 | 
						|
        # Assert
 | 
						|
        self.assert_image_equal(
 | 
						|
            im, Image.open("Tests/images/imagedraw_polygon.png"))
 | 
						|
 | 
						|
    def test_polygon1(self):
 | 
						|
        self.helper_polygon(POINTS1)
 | 
						|
 | 
						|
    def test_polygon2(self):
 | 
						|
        self.helper_polygon(POINTS2)
 | 
						|
 | 
						|
    def helper_rectangle(self, bbox):
 | 
						|
        # Arrange
 | 
						|
        im = Image.new("RGB", (W, H))
 | 
						|
        draw = ImageDraw.Draw(im)
 | 
						|
 | 
						|
        # Act
 | 
						|
        draw.rectangle(bbox, fill="black", outline="green")
 | 
						|
        del draw
 | 
						|
 | 
						|
        # Assert
 | 
						|
        self.assert_image_equal(
 | 
						|
            im, Image.open("Tests/images/imagedraw_rectangle.png"))
 | 
						|
 | 
						|
    def test_rectangle1(self):
 | 
						|
        self.helper_rectangle(BBOX1)
 | 
						|
 | 
						|
    def test_rectangle2(self):
 | 
						|
        self.helper_rectangle(BBOX2)
 | 
						|
 | 
						|
    def test_floodfill(self):
 | 
						|
        # Arrange
 | 
						|
        im = Image.new("RGB", (W, H))
 | 
						|
        draw = ImageDraw.Draw(im)
 | 
						|
        draw.rectangle(BBOX2, outline="yellow", fill="green")
 | 
						|
        centre_point = (int(W/2), int(H/2))
 | 
						|
 | 
						|
        # Act
 | 
						|
        ImageDraw.floodfill(im, centre_point, ImageColor.getrgb("red"))
 | 
						|
        del draw
 | 
						|
 | 
						|
        # Assert
 | 
						|
        self.assert_image_equal(
 | 
						|
            im, Image.open("Tests/images/imagedraw_floodfill.png"))
 | 
						|
 | 
						|
    @unittest.skipIf(hasattr(sys, 'pypy_version_info'),
 | 
						|
                     "Causes fatal RPython error on PyPy")
 | 
						|
    def test_floodfill_border(self):
 | 
						|
        # floodfill() is experimental
 | 
						|
 | 
						|
        # Arrange
 | 
						|
        im = Image.new("RGB", (W, H))
 | 
						|
        draw = ImageDraw.Draw(im)
 | 
						|
        draw.rectangle(BBOX2, outline="yellow", fill="green")
 | 
						|
        centre_point = (int(W/2), int(H/2))
 | 
						|
 | 
						|
        # Act
 | 
						|
        ImageDraw.floodfill(
 | 
						|
            im, centre_point, ImageColor.getrgb("red"),
 | 
						|
            border=ImageColor.getrgb("black"))
 | 
						|
        del draw
 | 
						|
 | 
						|
        # Assert
 | 
						|
        self.assert_image_equal(
 | 
						|
            im, Image.open("Tests/images/imagedraw_floodfill2.png"))
 | 
						|
 | 
						|
    def create_base_image_draw(self, size,
 | 
						|
                               mode=DEFAULT_MODE,
 | 
						|
                               background1=WHITE,
 | 
						|
                               background2=GRAY):
 | 
						|
        img = Image.new(mode, size, background1)
 | 
						|
        for x in range(0, size[0]):
 | 
						|
            for y in range(0, size[1]):
 | 
						|
                if (x + y) % 2 == 0:
 | 
						|
                    img.putpixel((x, y), background2)
 | 
						|
        return (img, ImageDraw.Draw(img))
 | 
						|
 | 
						|
    def test_square(self):
 | 
						|
        expected = Image.open(os.path.join(IMAGES_PATH, 'square.png'))
 | 
						|
        expected.load()
 | 
						|
        img, draw = self.create_base_image_draw((10, 10))
 | 
						|
        draw.polygon([(2, 2), (2, 7), (7, 7), (7, 2)], BLACK)
 | 
						|
        self.assert_image_equal(img, expected,
 | 
						|
                                'square as normal polygon failed')
 | 
						|
        img, draw = self.create_base_image_draw((10, 10))
 | 
						|
        draw.polygon([(7, 7), (7, 2), (2, 2), (2, 7)], BLACK)
 | 
						|
        self.assert_image_equal(img, expected,
 | 
						|
                                'square as inverted polygon failed')
 | 
						|
        img, draw = self.create_base_image_draw((10, 10))
 | 
						|
        draw.rectangle((2, 2, 7, 7), BLACK)
 | 
						|
        self.assert_image_equal(img, expected,
 | 
						|
                                'square as normal rectangle failed')
 | 
						|
        img, draw = self.create_base_image_draw((10, 10))
 | 
						|
        draw.rectangle((7, 7, 2, 2), BLACK)
 | 
						|
        self.assert_image_equal(
 | 
						|
            img, expected, 'square as inverted rectangle failed')
 | 
						|
 | 
						|
    def test_triangle_right(self):
 | 
						|
        expected = Image.open(os.path.join(IMAGES_PATH, 'triangle_right.png'))
 | 
						|
        expected.load()
 | 
						|
        img, draw = self.create_base_image_draw((20, 20))
 | 
						|
        draw.polygon([(3, 5), (17, 5), (10, 12)], BLACK)
 | 
						|
        self.assert_image_equal(img, expected, 'triangle right failed')
 | 
						|
 | 
						|
    def test_line_horizontal(self):
 | 
						|
        expected = Image.open(os.path.join(IMAGES_PATH,
 | 
						|
                              'line_horizontal_w2px_normal.png'))
 | 
						|
        expected.load()
 | 
						|
        img, draw = self.create_base_image_draw((20, 20))
 | 
						|
        draw.line((5, 5, 14, 5), BLACK, 2)
 | 
						|
        self.assert_image_equal(
 | 
						|
            img, expected, 'line straigth horizontal normal 2px wide failed')
 | 
						|
        expected = Image.open(os.path.join(IMAGES_PATH,
 | 
						|
                              'line_horizontal_w2px_inverted.png'))
 | 
						|
        expected.load()
 | 
						|
        img, draw = self.create_base_image_draw((20, 20))
 | 
						|
        draw.line((14, 5, 5, 5), BLACK, 2)
 | 
						|
        self.assert_image_equal(
 | 
						|
            img, expected, 'line straigth horizontal inverted 2px wide failed')
 | 
						|
        expected = Image.open(os.path.join(IMAGES_PATH,
 | 
						|
                              'line_horizontal_w3px.png'))
 | 
						|
        expected.load()
 | 
						|
        img, draw = self.create_base_image_draw((20, 20))
 | 
						|
        draw.line((5, 5, 14, 5), BLACK, 3)
 | 
						|
        self.assert_image_equal(
 | 
						|
            img, expected, 'line straigth horizontal normal 3px wide failed')
 | 
						|
        img, draw = self.create_base_image_draw((20, 20))
 | 
						|
        draw.line((14, 5, 5, 5), BLACK, 3)
 | 
						|
        self.assert_image_equal(
 | 
						|
            img, expected, 'line straigth horizontal inverted 3px wide failed')
 | 
						|
        expected = Image.open(os.path.join(IMAGES_PATH,
 | 
						|
                              'line_horizontal_w101px.png'))
 | 
						|
        expected.load()
 | 
						|
        img, draw = self.create_base_image_draw((200, 110))
 | 
						|
        draw.line((5, 55, 195, 55), BLACK, 101)
 | 
						|
        self.assert_image_equal(
 | 
						|
            img, expected, 'line straigth horizontal 101px wide failed')
 | 
						|
 | 
						|
    def test_line_h_s1_w2(self):
 | 
						|
        self.skipTest('failing')
 | 
						|
        expected = Image.open(os.path.join(IMAGES_PATH,
 | 
						|
                              'line_horizontal_slope1px_w2px.png'))
 | 
						|
        expected.load()
 | 
						|
        img, draw = self.create_base_image_draw((20, 20))
 | 
						|
        draw.line((5, 5, 14, 6), BLACK, 2)
 | 
						|
        self.assert_image_equal(
 | 
						|
            img, expected, 'line horizontal 1px slope 2px wide failed')
 | 
						|
 | 
						|
    def test_line_vertical(self):
 | 
						|
        expected = Image.open(os.path.join(IMAGES_PATH,
 | 
						|
                              'line_vertical_w2px_normal.png'))
 | 
						|
        expected.load()
 | 
						|
        img, draw = self.create_base_image_draw((20, 20))
 | 
						|
        draw.line((5, 5, 5, 14), BLACK, 2)
 | 
						|
        self.assert_image_equal(
 | 
						|
            img, expected, 'line straigth vertical normal 2px wide failed')
 | 
						|
        expected = Image.open(os.path.join(IMAGES_PATH,
 | 
						|
                              'line_vertical_w2px_inverted.png'))
 | 
						|
        expected.load()
 | 
						|
        img, draw = self.create_base_image_draw((20, 20))
 | 
						|
        draw.line((5, 14, 5, 5), BLACK, 2)
 | 
						|
        self.assert_image_equal(
 | 
						|
            img, expected, 'line straigth vertical inverted 2px wide failed')
 | 
						|
        expected = Image.open(os.path.join(IMAGES_PATH,
 | 
						|
                              'line_vertical_w3px.png'))
 | 
						|
        expected.load()
 | 
						|
        img, draw = self.create_base_image_draw((20, 20))
 | 
						|
        draw.line((5, 5, 5, 14), BLACK, 3)
 | 
						|
        self.assert_image_equal(
 | 
						|
            img, expected, 'line straigth vertical normal 3px wide failed')
 | 
						|
        img, draw = self.create_base_image_draw((20, 20))
 | 
						|
        draw.line((5, 14, 5, 5), BLACK, 3)
 | 
						|
        self.assert_image_equal(
 | 
						|
            img, expected, 'line straigth vertical inverted 3px wide failed')
 | 
						|
        expected = Image.open(os.path.join(IMAGES_PATH,
 | 
						|
                              'line_vertical_w101px.png'))
 | 
						|
        expected.load()
 | 
						|
        img, draw = self.create_base_image_draw((110, 200))
 | 
						|
        draw.line((55, 5, 55, 195), BLACK, 101)
 | 
						|
        self.assert_image_equal(img, expected,
 | 
						|
                                'line straigth vertical 101px wide failed')
 | 
						|
        expected = Image.open(os.path.join(IMAGES_PATH,
 | 
						|
                              'line_vertical_slope1px_w2px.png'))
 | 
						|
        expected.load()
 | 
						|
        img, draw = self.create_base_image_draw((20, 20))
 | 
						|
        draw.line((5, 5, 6, 14), BLACK, 2)
 | 
						|
        self.assert_image_equal(img, expected,
 | 
						|
                                'line vertical 1px slope 2px wide failed')
 | 
						|
 | 
						|
    def test_line_oblique_45(self):
 | 
						|
        expected = Image.open(os.path.join(IMAGES_PATH,
 | 
						|
                              'line_oblique_45_w3px_a.png'))
 | 
						|
        expected.load()
 | 
						|
        img, draw = self.create_base_image_draw((20, 20))
 | 
						|
        draw.line((5, 5, 14, 14), BLACK, 3)
 | 
						|
        self.assert_image_equal(img, expected,
 | 
						|
                                'line oblique 45 normal 3px wide A failed')
 | 
						|
        img, draw = self.create_base_image_draw((20, 20))
 | 
						|
        draw.line((14, 14, 5, 5), BLACK, 3)
 | 
						|
        self.assert_image_equal(img, expected,
 | 
						|
                                'line oblique 45 inverted 3px wide A failed')
 | 
						|
        expected = Image.open(os.path.join(IMAGES_PATH,
 | 
						|
                              'line_oblique_45_w3px_b.png'))
 | 
						|
        expected.load()
 | 
						|
        img, draw = self.create_base_image_draw((20, 20))
 | 
						|
        draw.line((14, 5, 5, 14), BLACK, 3)
 | 
						|
        self.assert_image_equal(img, expected,
 | 
						|
                                'line oblique 45 normal 3px wide B failed')
 | 
						|
        img, draw = self.create_base_image_draw((20, 20))
 | 
						|
        draw.line((5, 14, 14, 5), BLACK, 3)
 | 
						|
        self.assert_image_equal(img, expected,
 | 
						|
                                'line oblique 45 inverted 3px wide B failed')
 | 
						|
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    unittest.main()
 | 
						|
 | 
						|
# End of file
 |