Skip to content

Commit

Permalink
Added rounded_rectangle method
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Jan 15, 2021
1 parent 543fa2c commit 16087b2
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 0 deletions.
Binary file added Tests/images/imagedraw_rounded_rectangle.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions Tests/test_imagedraw.py
Expand Up @@ -699,6 +699,35 @@ def test_rectangle_I16():
)


@pytest.mark.parametrize(
"xy",
[(10, 20, 190, 180), ([10, 20], [190, 180]), ((10, 20), (190, 180))],
)
def test_rounded_rectangle(xy):
# Arrange
im = Image.new("RGB", (200, 200))
draw = ImageDraw.Draw(im)

# Act
draw.rounded_rectangle(xy, 30, fill="red", outline="green", width=5)

# Assert
assert_image_equal(im, Image.open("Tests/images/imagedraw_rounded_rectangle.png"))


def test_rounded_rectangle_zero_radius():
# Arrange
im = Image.new("RGB", (W, H))
draw = ImageDraw.Draw(im)
expected = "Tests/images/imagedraw_rectangle_width_fill.png"

# Act
draw.rounded_rectangle(BBOX1, 0, fill="blue", outline="green", width=5)

# Assert
assert_image_equal(im, Image.open(expected))


def test_floodfill():
red = ImageColor.getrgb("red")

Expand Down
14 changes: 14 additions & 0 deletions docs/reference/ImageDraw.rst
Expand Up @@ -285,6 +285,20 @@ Methods

.. versionadded:: 5.3.0

.. py:method:: ImageDraw.rounded_rectangle(xy, radius=0, fill=None, outline=None, width=1)
Draws a rounded rectangle.

:param xy: Two points to define the bounding box. Sequence of either
``[(x0, y0), (x1, y1)]`` or ``[x0, y0, x1, y1]``. The second point
is just outside the drawn rectangle.
:param radius: Radius of the corners.
:param outline: Color to use for the outline.
:param fill: Color to use for the fill.
:param width: The line width, in pixels.

.. versionadded:: 8.2.0

.. py:method:: ImageDraw.shape(shape, fill=None, outline=None)
.. warning:: This method is experimental.
Expand Down
47 changes: 47 additions & 0 deletions src/PIL/ImageDraw.py
Expand Up @@ -257,6 +257,53 @@ def rectangle(self, xy, fill=None, outline=None, width=1):
if ink is not None and ink != fill and width != 0:
self.draw.draw_rectangle(xy, ink, 0, width)

def rounded_rectangle(self, xy, radius=0, fill=None, outline=None, width=1):
"""Draw a rounded rectangle."""
if isinstance(xy[0], (list, tuple)):
(x0, y0), (x1, y1) = xy
else:
x0, y0, x1, y1 = xy

# Do not allow the diameter to be greater than the width or height
d = min(radius * 2, x1 - x0, y1 - y0)
if d == 0:
return self.rectangle(xy, fill, outline, width)

ink, fill = self._getink(outline, fill)
if fill is not None:
self.draw.draw_pieslice((x1 - d, y0, x1, y0 + d), 270, 360, fill, 1)
self.draw.draw_pieslice((x1 - d, y1 - d, x1, y1), 0, 90, fill, 1)
self.draw.draw_pieslice((x0, y1 - d, x0 + d, y1), 90, 180, fill, 1)
self.draw.draw_pieslice((x0, y0, x0 + d, y0 + d), 180, 270, fill, 1)

self.draw.draw_rectangle(
(x0 + d / 2 + 1, y0 + width, x1 - d / 2 - 1, y1 - width), fill, 1
)
self.draw.draw_rectangle(
(x0 + width, y0 + d / 2 + 1, x0 + d / 2, y1 - d / 2 - 1), fill, 1
)
self.draw.draw_rectangle(
(x1 - d / 2, y0 + d / 2 + 1, x1 - width, y1 - d / 2 - 1), fill, 1
)
if ink is not None and ink != fill and width != 0:
self.draw.draw_arc((x1 - d, y0, x1, y0 + d), 270, 360, ink, width)
self.draw.draw_arc((x1 - d, y1 - d, x1, y1), 0, 90, ink, width)
self.draw.draw_arc((x0, y1 - d, x0 + d, y1), 90, 180, ink, width)
self.draw.draw_arc((x0, y0, x0 + d, y0 + d), 180, 270, ink, width)

self.draw.draw_rectangle(
(x1 - width + 1, y0 + d / 2 + 1, x1, y1 - d / 2 - 1), ink, 1
)
self.draw.draw_rectangle(
(x0 + d / 2 + 1, y1 - width + 1, x1 - d / 2 - 1, y1), ink, 1
)
self.draw.draw_rectangle(
(x0, y0 + d / 2 + 1, x0 + width - 1, y1 - d / 2 - 1), ink, 1
)
self.draw.draw_rectangle(
(x0 + d / 2 + 1, y0, x1 - d / 2 - 1, y0 + width - 1), ink, 1
)

def _multiline_check(self, text):
"""Draw text."""
split_character = "\n" if isinstance(text, str) else b"\n"
Expand Down

0 comments on commit 16087b2

Please sign in to comment.