diff --git a/PIL/ImageDraw.py b/PIL/ImageDraw.py index 72040392001..efe84048632 100644 --- a/PIL/ImageDraw.py +++ b/PIL/ImageDraw.py @@ -217,12 +217,11 @@ def _multiline_split(self, text): return text.split(split_character) - def text(self, xy, text, fill=None, font=None, anchor=None, - *args, **kwargs): + def text(self, xy, text, fill=None, font=None, anchor=None, spacing=4, + align="left", outline=None): if self._multiline_check(text): return self.multiline_text(xy, text, fill, font, anchor, - *args, **kwargs) - + spacing, align, outline) ink, fill = self._getink(fill) if font is None: font = self.getfont() @@ -237,10 +236,17 @@ def text(self, xy, text, fill=None, font=None, anchor=None, mask = font.getmask(text, self.fontmode) except TypeError: mask = font.getmask(text) + if outline is not None: + color, _ = self._getink(outline) + for offset in range(0, 2): + tmp_xy = list(xy) + for difference in [-1, 1]: + tmp_xy[offset] = xy[offset] + difference + self.draw.draw_bitmap(tmp_xy, mask, color) self.draw.draw_bitmap(xy, mask, ink) def multiline_text(self, xy, text, fill=None, font=None, anchor=None, - spacing=4, align="left"): + spacing=4, align="left", outline=None): widths = [] max_width = 0 lines = self._multiline_split(text) @@ -259,10 +265,9 @@ def multiline_text(self, xy, text, fill=None, font=None, anchor=None, left += (max_width - widths[idx]) else: assert False, 'align must be "left", "center" or "right"' - self.text((left, top), line, fill, font, anchor) + self.text((left, top), line, fill, font, anchor, outline=outline) top += line_spacing left = xy[0] - def textsize(self, text, font=None, *args, **kwargs): """Get the size of a given string, in pixels.""" if self._multiline_check(text): diff --git a/Tests/images/stroked_text_image.png b/Tests/images/stroked_text_image.png new file mode 100644 index 00000000000..90c3282d286 Binary files /dev/null and b/Tests/images/stroked_text_image.png differ diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index de89ac92974..a1910983c29 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -127,6 +127,18 @@ def test_textsize_equal(self): target_img = Image.open(target) self.assert_image_similar(im, target_img, .5) + def test_stroke_text(self): + im = Image.new(mode='RGB', size=(300, 100)) + draw = ImageDraw.Draw(im) + ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE) + + draw.text((5, 5), TEST_TEXT, 'black', font=ttf, + outline='white') + + target = 'Tests/images/stroked_text_image.png' + target_img = Image.open(target) + self.assert_image_similar(im, target_img, .5) + def test_render_multiline(self): im = Image.new(mode='RGB', size=(300, 100)) draw = ImageDraw.Draw(im) diff --git a/docs/reference/ImageDraw.rst b/docs/reference/ImageDraw.rst index 842407c9092..53c83ee7da4 100644 --- a/docs/reference/ImageDraw.rst +++ b/docs/reference/ImageDraw.rst @@ -240,6 +240,7 @@ Methods the number of pixels between lines. :param align: If the text is passed on to multiline_text(), "left", "center" or "right". + :param outline: Color to use to draw an outline around the text. .. py:method:: PIL.ImageDraw.Draw.multiline_text(xy, text, fill=None, font=None, anchor=None, spacing=0, align="left") @@ -252,6 +253,7 @@ Methods :param font: An :py:class:`~PIL.ImageFont.ImageFont` instance. :param spacing: The number of pixels between lines. :param align: "left", "center" or "right". + :param outline: Color to use to draw an outline around the text. .. py:method:: PIL.ImageDraw.Draw.textsize(text, font=None, spacing=0) diff --git a/docs/releasenotes/3.5.0.rst b/docs/releasenotes/3.5.0.rst new file mode 100644 index 00000000000..eb6d665acc2 --- /dev/null +++ b/docs/releasenotes/3.5.0.rst @@ -0,0 +1,10 @@ +3.5.0 +----- + +New text-outlining feature +========================== + +Both ``ImageDraw.text()`` and ``ImageDraw.multiline_text()`` now supports +text-stroking. +Passing in a color value to the methods using the ``outline`` keyword argument +will now outline the text in that color. diff --git a/docs/releasenotes/index.rst b/docs/releasenotes/index.rst index 8c484af4473..920dc8834b0 100644 --- a/docs/releasenotes/index.rst +++ b/docs/releasenotes/index.rst @@ -6,6 +6,7 @@ Release Notes .. toctree:: :maxdepth: 2 + 3.5.0 3.4.0 3.3.2 3.3.0