from PIL import Image, ImageDraw, ImageFont
width = 300
height = 100
text = "Hello World"
font_name = 'Ubuntu-M'
# --- create image for text ---
img = Image.new('RGB', (width, height), (255, 255, 255))
draw = ImageDraw.Draw(img)
# --- calculate font size, box ---
# default values at start
font_size = None # for font size
font = None # for object truetype with correct font size
box = None # for version 8.0.0
# test for different font sizes
for size in range(1, 500):
# create new font
new_font = ImageFont.truetype(font_name, size)
# calculate bbox for version 8.0.0
new_box = draw.textbbox((0, 0), text, new_font) # need 8.0.0
# `bbox` may have top/left margin so calculate real width/height
new_w = new_box[2] - new_box[0] # bottom-top
new_h = new_box[3] - new_box[1] # right-left
#print(size, '|', new_w, new_h, '|', new_box)
# if too big then exit with previous values
if new_w > width or new_h > height:
break
# set new current values as current values
font_size = size
font = new_font
box = new_box
w = new_w
h = new_h
# --- use it ---
print('font size:', font_size)
print('box:', box)
print('w <= width :', w, '<=', width)
print('h <= height:', h, '<=', height)
# calculate position (minus margins in box)
x = (width - w)//2 - box[0] # minus left margin
y = (height - h)//2 - box[3] # minus top margin
print('w,h (without margins):', w, h)
print('x,y (without margins):', x, y)
# draw it
draw.text((x, y), text, (0, 0, 0), font)
# display result
img.show()
img.save('result-textbbox.png', 'png')
编辑:**
与函数相同
from PIL import Image, ImageDraw, ImageFont
def get_font(img, text, font_name, width, height):
# default values at start
font_size = None # for font size
font = None # for object truetype with correct font size
box = None # for version 8.0.0
# test for different font sizes
for size in range(1, 500):
# create new font
new_font = ImageFont.truetype(font_name, size)
# calculate bbox for version 8.0.0
new_box = draw.textbbox((0, 0), text, new_font) # need 8.0.0
# `bbox` may have top/left margin so calculate real width/height
new_w = new_box[2] - new_box[0] # bottom-top
new_h = new_box[3] - new_box[1] # right-left
#print(size, '|', new_w, new_h, '|', new_box)
# if too big then exit with previous values
if new_w > width or new_h > height:
break
# set new current values as current values
font_size = size
font = new_font
box = new_box
w = new_w
h = new_h
# calculate position (minus margins in box)
x = (width - w)//2 - box[0] # minus left margin
y = (height - h)//2 - box[1] # minus top margin
return font, font_size, box, w, h, x, y
# --- main ---
width = 300
height = 100
text = "World"
font_name = 'Ubuntu-M'
# --- create image for text ---
img = Image.new('RGB', (width, height), (200, 255, 255))
draw = ImageDraw.Draw(img)
# --- calculate font size, box ---
font, font_size, box, w, h, x, y = get_font(img, text, font_name, width, height)
# --- use it ---
print('font size:', font_size)
print('box:', box)
print('w <= width :', w, '<=', width)
print('h <= height:', h, '<=', height)
print('w,h (without margins):', w, h)
print('x,y (without margins):', x, y)
# draw it
draw.text((x, y), text, (0, 0, 0), font)
# display result
img.show()
img.save('result-textbbox.png', 'png')
1条答案
按热度按时间5jdjgkvh1#
除了
for
循环中的ImageDraw.textsize()
之外,我不知道还有其他方法可以检查不同的字体大小。现在我发现在8.0.0版本中,他们添加了
ImageDraw.textbbox()
,这给出了更好的结果,因为它还计算顶部边距,可以用来更好地计算位置。但是它仍然需要
for
-loop来检查它是否有不同的字体大小。textsize
的结果:textbbox
的结果(垂直居中):这是我计算字体大小和方框大小的例子,直接用它来计算
与函数相同