This commit is contained in:
Micah Chambers 2016-05-24 15:57:34 +00:00
parent 2defce3431
commit 033661c17f

View File

@ -295,7 +295,7 @@ class ImageDraw(object):
# The best lineHeight would be that returned from the font.font.height # The best lineHeight would be that returned from the font.font.height
# attribute, but in versions of PIL in which that isn't accessible, # attribute, but in versions of PIL in which that isn't accessible,
# sum( font.getmetrics()) is used instead. # sum( font.getmetrics()) is used instead.
def textInfo( self, text, font=None, lineHeight=None, lineHeightPercent=None ): def textInfo(self, text, font=None, lineHeight=None, lineHeightPercent=None):
if font is None: if font is None:
font = self.getfont() font = self.getfont()
lines = text.split('\n') lines = text.split('\n')
@ -304,20 +304,20 @@ class ImageDraw(object):
txWid = 0 txWid = 0
tyMax = None tyMax = None
tyMin = None tyMin = None
if len( lines ) > 1: if len(lines) > 1:
if lineHeight is None: if lineHeight is None:
if lineHeightPercent is None: if lineHeightPercent is None:
lineHeightPercent = 100 lineHeightPercent = 100
try: try:
lineHeight = font.font.height lineHeight = font.font.height
except Exception as exc: except AttributeError:
lineHeight = sum( font.getmetrics()) lineHeight = sum(font.getmetrics())
lineHeight = int( lineHeight * lineHeightPercent / 100 ) lineHeight = int(lineHeight * lineHeightPercent / 100)
lineBBs = [] lineBBs = []
for line in lines: for line in lines:
lxMin, lyMin, lxMax, lyMax = font.getBB( line ) lxMin, lyMin, lxMax, lyMax = font.getBB(line)
lineBBs.append(( lxMin, lyMin, lxMax, lyMax, line )) lineBBs.append((lxMin, lyMin, lxMax, lyMax, line))
lxWid = lxMax - lxMin lxWid = lxMax - lxMin
if txWid < lxWid: if txWid < lxWid:
txWid = lxWid txWid = lxWid
@ -326,13 +326,13 @@ class ImageDraw(object):
if txMin > lxMin: if txMin > lxMin:
txMin = lxMin txMin = lxMin
if tyMax is None: if tyMax is None:
tyMax = lyMax # from first line only tyMax = lyMax # from first line only
if tyMin is None: if tyMin is None:
tyMin = 0 # skips first line (unless it is also last) tyMin = 0 # skips first line (unless it is also last)
else: else:
tyMin -= lineHeight tyMin -= lineHeight
tyMin += lyMin # from last line tyMin += lyMin # from last line
return ( txMin, tyMin, txMax, tyMax, txWid, lineHeight, lineBBs ) return (txMin, tyMin, txMax, tyMax, txWid, lineHeight, lineBBs)
# Text is drawn as close as possible to the specified alignment edges of the # Text is drawn as close as possible to the specified alignment edges of the
# image, without truncation on those edges, then adjusted by the origin value. # image, without truncation on those edges, then adjusted by the origin value.
@ -341,45 +341,44 @@ class ImageDraw(object):
# alignment position. alignX can also be 'left', 'center', or 'right'; alignY # alignment position. alignX can also be 'left', 'center', or 'right'; alignY
# can also be 'top', 'middle', or 'bottom'. justifyX can be 'left', 'center', # can also be 'top', 'middle', or 'bottom'. justifyX can be 'left', 'center',
# or 'right'. Other parameters like textInfo. # or 'right'. Other parameters like textInfo.
def textAtPos( self, text, font=None, lineHeight=None, lineHeightPercent=None, def textAtPos(self, text, font=None, lineHeight=None, lineHeightPercent=None,
origin=( 0, 0 ), alignX='exact', alignY='exact', justifyX='left', origin=(0, 0), alignX='exact', alignY='exact', justifyX='left',
fill=None ): fill=None):
if font is None: if font is None:
font = self.getfont() font = self.getfont()
ink, fill = self._getink( fill ) ink, fill = self._getink(fill)
if ink is None: if ink is None:
inx = fill
if ink is None: if ink is None:
return return
if justifyX not in ('left', 'center', 'right'): if justifyX not in ('left', 'center', 'right'):
raise ValueError('Unknown justifyX value "%s".' % justifyX ) raise ValueError('Unknown justifyX value "%s".' % justifyX)
txMin, tyMin, txMax, tyMax, txWid, lineHeight, lineBBs = self.textInfo( txMin, tyMin, txMax, tyMax, txWid, lineHeight, lineBBs = self.textInfo(
text, font, lineHeight, lineHeightPercent ) text, font, lineHeight, lineHeightPercent)
if alignX == 'exact': if alignX == 'exact':
ox = 0 ox = 0
elif alignX == 'left': elif alignX == 'left':
ox = -txMin ox = -txMin
elif alignX == 'right': elif alignX == 'right':
ox = self.im.size[ 0 ] - txMax ox = self.im.size[0] - txMax
elif alignX == 'center': elif alignX == 'center':
ox = self.im.size[ 0 ] // 2 - txMax // 2 ox = self.im.size[0] // 2 - txMax // 2
else: else:
raise ValueError('Unknown alignX value "%s".' % alignX ) raise ValueError('Unknown alignX value "%s".' % alignX)
if alignY == 'exact': if alignY == 'exact':
oy = 0 oy = 0
elif alignY == 'top': elif alignY == 'top':
oy = tyMax oy = tyMax
elif alignY == 'bottom': elif alignY == 'bottom':
oy = self.im.size[ 1 ] + tyMin oy = self.im.size[1] + tyMin
elif alignY == 'middle': elif alignY == 'middle':
oy = self.im.size[ 1 ] // 2 + ( tyMax + tyMin ) // 2 oy = self.im.size[1] // 2 + (tyMax + tyMin) // 2
else: else:
raise ValueError('Unknown alignY value "%s".' % alignY ) raise ValueError('Unknown alignY value "%s".' % alignY)
ox += origin[ 0 ] ox += origin[0]
oy += origin[ 1 ] oy += origin[1]
ascent, descent = font.getmetrics() ascent, descent = font.getmetrics()
while lineBBs: while lineBBs:
lxMin, lyMin, lxMax, lyMax, line = lineBBs.pop( 0 ) lxMin, lyMin, lxMax, lyMax, line = lineBBs.pop(0)
if justifyX == 'left': if justifyX == 'left':
lox = ox lox = ox
elif justifyX == 'right': elif justifyX == 'right':
@ -390,14 +389,24 @@ class ImageDraw(object):
# finally, draw some text # finally, draw some text
lox = lox + lxMin lox = lox + lxMin
loy = oy - lyMax loy = oy - lyMax
im = Image.core.fill("L", ( lxMax - lxMin, lyMax - lyMin ), 0 ) im = Image.core.fill("L", (lxMax - lxMin, lyMax - lyMin), 0)
font.font.render( line, im.id, self.fontmode == "1" ) font.font.render(line, im.id, self.fontmode == "1")
self.draw.draw_bitmap(( lox, loy ), im, ink ) self.draw.draw_bitmap((lox, loy), im, ink)
if not lineBBs: if not lineBBs:
break break
oy += lineHeight oy += lineHeight
##
# A simple 2D drawing interface for PIL images.
#
# @param im The image to draw in.
# @param mode Optional mode to use for color values. For RGB
# images, this argument can be RGB or RGBA (to blend the
# drawing into the image). For all other modes, this argument
# must be the same as the image mode. If omitted, the mode
# defaults to the mode of the image.
def Draw(im, mode=None): def Draw(im, mode=None):
""" """
A simple 2D drawing interface for PIL images. A simple 2D drawing interface for PIL images.