text_width property of FontMetric doesn't seem accurate #618
-
I'm trying to add text to an image that I'm making from a resized SVG. I've got a simple algorithm to figure out the largest font size that will fit in the final image, but I seem to be misunderstanding the properties in #!/usr/bin/env python3
from wand.color import Color
from wand.image import Image
from wand.drawing import Drawing
def generate_message(message: str):
with Image(filename='Opensource.svg', resolution=4096, background=Color('transparent')) as image:
image.resize(2400, 1697 * 2)
image.extent(width=2400, height=1697 * 2,gravity='south')
with Drawing() as draw:
draw.gravity = 'north'
draw.font_size = 10
while True:
metrics = draw.get_font_metrics(image, message)
#if metrics.text_width >= image.width: #this also doesn't work
if metrics.text_width >= 2048: #checking the width of the text here against the desired width
draw.font_size -= 0.1
else:
break
draw.text(0, 0, message)
draw(image)
image.save(filename='test.png')
if __name__ == '__main__':
generate_message('hey yous guys') Does this make sense or am I thinking of this wrong? I expect the text to be as large as it can be without going past the left or right edges. Is there a better way to do this? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
Have you tried just generating the text as a new image, and composing over the source image? from wand.image import Image
kFontPath = '/usr/share/fonts/google-noto-vf/NotoSans-VF.ttf'
def faster_generate_message(msg):
with Image(filename='wizard:') as img:
dim = img.size
with Image() as txt:
# Set typeface properties before reading label:
txt.background_color = 'transparent'
txt.font_color = 'magenta'
txt.font_path = kFontPath
# Picking either the min / max will generate a real large image.
txt.font_size = min(*dim)
txt.read(filename='label:' + msg)
# If we want message to hit the border of the image.
txt.trim(fuzz=0.1*txt.quantum_range)
# Resize respecting the largest side.
txt.transform(resize='{0}x{1}>'.format(*dim))
# Compose over the original image.
img.composite(txt, gravity='center')
# Just to show the image when displayed online.
img.border('cyan', 1, 1)
img.save(filename='output.png')
if __name__ == '__main__':
faster_generate_message('hey yous guys\nI\'ve got multiple lines!') |
Beta Was this translation helpful? Give feedback.
-
That is incredible! Thank you! |
Beta Was this translation helpful? Give feedback.
Have you tried just generating the text as a new image, and composing over the source image?