Add outline feature to ImageDraw.text()

This change adds an additional method argument to the draw() method
which draws the text in black, before drawing it in the color selected
in the fill parameter.

Additionally due to the positional requirements enforced on the method
by using **kwargs, move to using an explicit signature with default values.

* Helps improve readability
* Allows for easier modification later.
This commit is contained in:
Paddez 2016-11-15 10:48:31 +00:00
parent 76d156bef0
commit a22eedad07
No known key found for this signature in database
GPG Key ID: 1DB178216DA02CD1
3 changed files with 25 additions and 7 deletions

View File

@ -217,13 +217,13 @@ class ImageDraw(object):
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)
print("Outline: %s" % outline)
if font is None:
font = self.getfont()
if ink is None:
@ -237,10 +237,17 @@ class ImageDraw(object):
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 +266,9 @@ class ImageDraw(object):
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):

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -127,6 +127,18 @@ try:
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)