diff --git a/Tests/images/imagedraw2_text.png b/Tests/images/imagedraw2_text.png new file mode 100644 index 000000000..b22e6545b Binary files /dev/null and b/Tests/images/imagedraw2_text.png differ diff --git a/Tests/test_imagedraw2.py b/Tests/test_imagedraw2.py new file mode 100644 index 000000000..c5faeb616 --- /dev/null +++ b/Tests/test_imagedraw2.py @@ -0,0 +1,229 @@ +import os.path + +from helper import PillowTestCase, hopper, unittest +from PIL import Image, ImageDraw2, features + +BLACK = (0, 0, 0) +WHITE = (255, 255, 255) +GRAY = (190, 190, 190) +DEFAULT_MODE = "RGB" +IMAGES_PATH = os.path.join("Tests", "images", "imagedraw") + +# 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] + +KITE_POINTS = [(10, 50), (70, 10), (90, 50), (70, 90), (10, 50)] + +HAS_FREETYPE = features.check("freetype2") +FONT_PATH = "Tests/fonts/FreeMono.ttf" + + +class TestImageDraw(PillowTestCase): + + def test_sanity(self): + im = hopper("RGB").copy() + + draw = ImageDraw2.Draw(im) + pen = ImageDraw2.Pen("blue", width=7) + draw.line(list(range(10)), pen) + + from PIL import ImageDraw + + draw, handler = ImageDraw.getdraw(im) + pen = ImageDraw2.Pen("blue", width=7) + draw.line(list(range(10)), pen) + + def helper_ellipse(self, mode, bbox): + # Arrange + im = Image.new("RGB", (W, H)) + draw = ImageDraw2.Draw(im) + pen = ImageDraw2.Pen("blue", width=2) + brush = ImageDraw2.Brush("green") + expected = "Tests/images/imagedraw_ellipse_{}.png".format(mode) + + # Act + draw.ellipse(bbox, pen, brush) + + # Assert + self.assert_image_similar(im, Image.open(expected), 1) + + def test_ellipse1(self): + self.helper_ellipse("RGB", BBOX1) + + def test_ellipse2(self): + self.helper_ellipse("RGB", BBOX2) + + def test_ellipse_edge(self): + # Arrange + im = Image.new("RGB", (W, H)) + draw = ImageDraw2.Draw(im) + brush = ImageDraw2.Brush("white") + + # Act + draw.ellipse(((0, 0), (W-1, H)), brush) + + # Assert + self.assert_image_similar( + im, Image.open("Tests/images/imagedraw_ellipse_edge.png"), 1) + + def helper_line(self, points): + # Arrange + im = Image.new("RGB", (W, H)) + draw = ImageDraw2.Draw(im) + pen = ImageDraw2.Pen("yellow", width=2) + + # Act + draw.line(points, pen) + + # Assert + self.assert_image_equal( + im, Image.open("Tests/images/imagedraw_line.png")) + + def test_line1_pen(self): + self.helper_line(POINTS1) + + def test_line2_pen(self): + self.helper_line(POINTS2) + + def test_line_pen_as_brush(self): + # Arrange + im = Image.new("RGB", (W, H)) + draw = ImageDraw2.Draw(im) + pen = None + brush = ImageDraw2.Pen("yellow", width=2) + + # Act + # Pass in the pen as the brush parameter + draw.line(POINTS1, pen, brush) + + # Assert + self.assert_image_equal( + im, Image.open("Tests/images/imagedraw_line.png")) + + def helper_polygon(self, points): + # Arrange + im = Image.new("RGB", (W, H)) + draw = ImageDraw2.Draw(im) + pen = ImageDraw2.Pen("blue", width=2) + brush = ImageDraw2.Brush("red") + + # Act + draw.polygon(points, pen, brush) + + # 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 = ImageDraw2.Draw(im) + pen = ImageDraw2.Pen("green", width=2) + brush = ImageDraw2.Brush("black") + + # Act + draw.rectangle(bbox, pen, brush) + + # 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_big_rectangle(self): + # Test drawing a rectangle bigger than the image + # Arrange + im = Image.new("RGB", (W, H)) + bbox = [(-1, -1), (W + 1, H + 1)] + brush = ImageDraw2.Brush("orange") + draw = ImageDraw2.Draw(im) + expected = "Tests/images/imagedraw_big_rectangle.png" + + # Act + draw.rectangle(bbox, brush) + + # Assert + self.assert_image_similar(im, Image.open(expected), 1) + + @unittest.skipUnless(HAS_FREETYPE, "ImageFont not available") + def test_text(self): + # Arrange + im = Image.new("RGB", (W, H)) + draw = ImageDraw2.Draw(im) + font = ImageDraw2.Font("white", FONT_PATH) + expected = "Tests/images/imagedraw2_text.png" + + # Act + draw.text((5, 5), "ImageDraw2", font) + + # Assert + self.assert_image_similar(im, Image.open(expected), 13) + + @unittest.skipUnless(HAS_FREETYPE, "ImageFont not available") + def test_textsize(self): + # Arrange + im = Image.new("RGB", (W, H)) + draw = ImageDraw2.Draw(im) + font = ImageDraw2.Font("white", FONT_PATH) + + # Act + size = draw.textsize("ImageDraw2", font) + + # Assert + self.assertEqual(size[1], 12) + + @unittest.skipUnless(HAS_FREETYPE, "ImageFont not available") + def test_textsize_empty_string(self): + # Arrange + im = Image.new("RGB", (W, H)) + draw = ImageDraw2.Draw(im) + font = ImageDraw2.Font("white", FONT_PATH) + + # Act + # Should not cause 'SystemError: returned NULL without setting an error' + draw.textsize("", font) + draw.textsize("\n", font) + draw.textsize("test\n", font) + + @unittest.skipUnless(HAS_FREETYPE, "ImageFont not available") + def test_flush(self): + # Arrange + im = Image.new("RGB", (W, H)) + draw = ImageDraw2.Draw(im) + font = ImageDraw2.Font("white", FONT_PATH) + + # Act + draw.text((5, 5), "ImageDraw2", font) + im2 = draw.flush() + + # Assert + self.assert_image_equal(im, im2) + + +if __name__ == "__main__": + unittest.main() diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index 986b0b5ef..4d36334e1 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -42,7 +42,7 @@ class SimplePatcher(object): delattr(self._parent_obj, self._attr_name) -@unittest.skipUnless(HAS_FREETYPE, "ImageFont not Available") +@unittest.skipUnless(HAS_FREETYPE, "ImageFont not available") class TestImageFont(PillowTestCase): LAYOUT_ENGINE = ImageFont.LAYOUT_BASIC diff --git a/src/PIL/ImageDraw2.py b/src/PIL/ImageDraw2.py index a1763350d..f7902b031 100644 --- a/src/PIL/ImageDraw2.py +++ b/src/PIL/ImageDraw2.py @@ -98,9 +98,6 @@ class Draw(object): def rectangle(self, xy, *options): self.render("rectangle", xy, *options) - def symbol(self, xy, symbol, *options): - raise NotImplementedError("not in this version") - def text(self, xy, text, font): if self.transform: xy = ImagePath.Path(xy)