Files
ansible/lib/python3.10/site-packages/svg/path/tests/test_image.py
2023-02-08 12:13:28 +01:00

133 lines
4.4 KiB
Python

import unittest
import os
from PIL import Image, ImageDraw, ImageColor, ImageChops
from math import sqrt
from ..path import CubicBezier, QuadraticBezier, Line, Arc
RED = ImageColor.getcolor("red", mode="RGB")
GREEN = ImageColor.getcolor("limegreen", mode="RGB")
BLUE = ImageColor.getcolor("cornflowerblue", mode="RGB")
YELLOW = ImageColor.getcolor("yellow", mode="RGB")
CYAN = ImageColor.getcolor("cyan", mode="RGB")
WHITE = ImageColor.getcolor("white", mode="RGB")
BLACK = ImageColor.getcolor("black", mode="RGB")
DOT = 4 + 4j # x+y radius of dot
def c2t(c):
"""Make a complex number into a tuple"""
return c.real, c.imag
def magnitude(c):
return sqrt(c.real**2 + c.imag**2)
class ImageTest(unittest.TestCase):
"""Creates a PNG image and compares with a correct PNG"""
def setUp(self):
self.image = Image.new(mode="RGB", size=(500, 1200))
self.draw = ImageDraw.Draw(self.image)
def draw_path(self, path):
lines = [c2t(path.point(x * 0.01)) for x in range(1, 101)]
self.draw.line(lines, fill=WHITE, width=2)
p = path.point(0)
self.draw.ellipse([c2t(p - DOT), c2t(p + DOT)], fill=BLUE)
p = path.point(1)
self.draw.ellipse([c2t(p - DOT), c2t(p + DOT)], fill=GREEN)
def draw_tangents(self, path, count):
count += 1
for i in range(1, count):
p = path.point(i / count)
t = path.tangent(i / count)
self.draw.line([c2t(p), c2t(p + t)], fill=RED, width=1)
# And a nice 90 angle
tt = complex(t.imag, -t.real)
# scale it to always be 20px
tt *= 20 / magnitude(tt)
self.draw.line([c2t(p), c2t(tt + p)], fill=YELLOW, width=1)
def test_image(self):
self.draw.text((10, 10), "This is an SVG line:")
self.draw.text(
(10, 100),
"The red line is a tangent, and the yellow is 90 degrees from that.",
)
line1 = Line(40 + 60j, 200 + 80j)
self.draw_path(line1)
self.draw_tangents(line1, 1)
self.draw.text((10, 140), "This is an Arc segment, almost a whole circle:")
arc1 = Arc(260 + 320j, 100 + 100j, 0, 1, 1, 260 + 319j)
self.draw_path(arc1)
self.draw_tangents(arc1, 5)
self.draw.text((10, 460), "With five tangents.")
self.draw.text(
(10, 500),
"Next we have a quadratic bezier curve, with one tangent:",
)
start = 30 + 600j
control = 400 + 540j
end = 260 + 650j
qbez1 = QuadraticBezier(start, control, end)
self.draw_path(qbez1)
self.draw.ellipse([c2t(control - DOT), c2t(control + DOT)], fill=WHITE)
self.draw.line([c2t(start), c2t(control), c2t(end)], fill=CYAN)
self.draw_tangents(qbez1, 1)
self.draw.text(
(10, 670),
"The white dot is the control point, and the cyan lines are ",
)
self.draw.text((10, 690), "illustrating the how the control point works.")
self.draw.text(
(10, 730),
"Lastly is a cubic bezier, with 2 tangents, and 2 control points:",
)
start = 30 + 800j
control1 = 400 + 780j
control2 = 50 + 900j
end = 300 + 980j
cbez1 = CubicBezier(start, control1, control2, end)
self.draw_path(cbez1)
self.draw.ellipse([c2t(control1 - DOT), c2t(control1 + DOT)], fill=WHITE)
self.draw.ellipse([c2t(control2 - DOT), c2t(control2 + DOT)], fill=WHITE)
self.draw.line(
[
c2t(start),
c2t(control1),
],
fill=CYAN,
)
self.draw.line([c2t(control2), c2t(end)], fill=CYAN)
self.draw_tangents(cbez1, 2)
# self.image.show() # Useful when debugging
filename = os.path.join(os.path.split(__file__)[0], "test_image.png")
# If you have made intentional changes to the test_image.png, save it
# by uncommenting these lines. Don't forget to comment them out again,
# or the test will always pass
# with open(filename, "wb") as fp:
# self.image.save(fp, format="PNG")
with open(filename, "rb") as fp:
test_image = Image.open(fp, mode="r")
diff = ImageChops.difference(test_image, self.image)
self.assertFalse(
diff.getbbox(), "The resulting image is different from test_image.png"
)