我正在开发一个工具,可以将文本添加到图像的特定区域,比如在演讲气泡中。我正在生成一个边界框,并希望将文本限制为仅在此边界框内,但到目前为止,查看cv2和PIL库时,它们似乎只作为文本的起点,而不是边界框。
cv2:
import cv2
myimg = "471.jpg"
img = cv2.imread(myimg)
f_face = cv2.FONT_HERSHEY_PLAIN
f_size = 1
f_color = (255,255,255)
f_thickness = 2
text = 'Hello World'
x,y = 400,800
img = cv2.putText(img, text, (x,y), f_face, f_size, f_color, f_thickness)
cv2.imshow("Test", img)
cv2.waitKey(0)
cv2.destroyAllWindows()PIL:
from PIL import Image
from PIL import ImageDraw
myimg = "471.jpg"
img = Image.open(myimg)
id = ImageDraw.Draw(img)
id.text((400, 800), "Hello World", fill=(255, 255, 255))
img.show()理想情况下,我会寻找一个库,它可以让我像使用Photoshop时一样控制文本,这意味着:字体大小,字体外观,垂直居中(到边界框/文本框)和水平居中(到边界框/文本框),以及自动调整字体大小或边界框以适应文本,而不会被切断(或者至少给出文本框溢出的某种警告,以便我可以进行一个减小字体大小的过程并重试)。
有没有其他的库有这样的控制?或者,在cv2或PIL中有这样做的方法吗?
谢谢你的帮助
发布于 2021-05-30 22:07:47
Pillow有ImageFont来选择字体,字体大小,你可以在text(..., font=...)中使用。
在较新的版本中,您可以使用text((center_x, center_y), anchor='mm')在区域中居中显示文本。更多信息请访问:Text Anchor
问题只会导致自动调整字体大小。
您必须使用ImageFont.FreeTypeFont.getbbox()来计算具有选定字体大小的文本所使用的区域大小。如果你使用for-loop来计算不同字体大小的区域大小,那么你可以自动调整大小。
import PIL
print('PIL version:', PIL.__version__)
from PIL import Image, ImageDraw, ImageFont
# create empty image
img = Image.new(size=(400, 300), mode='RGB')
draw = ImageDraw.Draw(img)
# draw white rectangle 200x100 with center in 200,150
draw.rectangle((200-100, 150-50, 200+100, 150+50), fill='white')
draw.line(((0, 150), (400, 150)), 'gray')
draw.line(((200, 0), (200, 300)), 'gray')
# find font size for text `"Hello World"` to fit in rectangle 200x100
selected_size = 1
for size in range(1, 150):
arial = ImageFont.FreeTypeFont('/home/furas/.wine/drive_c/windows/Fonts/arial.ttf', size=size)
w, h = arial.getsize("Hello World") # older versions
#left, top, right, bottom = arial.getbbox("Hello World") # needs PIL 8.0.0
#w = right - left
#h = bottom - top
print(w, h)
if w > 200 or h > 100:
break
selected_size = size
print(arial.size)
# draw text in center of rectangle 200x100
arial = ImageFont.FreeTypeFont('/home/furas/.wine/drive_c/windows/Fonts/arial.ttf', size=selected_size)
#draw.text((200-w//2, 150-h//2), "Hello World", fill='black', font=arial) # older versions
#img.save('center-older.png')
draw.text((200, 150), "Hello World", fill='black', anchor='mm', font=arial)
img.save('center-newer.png')
img.show()(200-w//2, 150-h//2)和getbbox()的结果

(200-w//2, 150-h//2)和getsize()的结果

使用anchor='mm' (使用getbbox()或getsize())的结果

https://stackoverflow.com/questions/67760340
复制相似问题