在 Wand 中为文本动画构建帧

Build frames for a text animation in Wand

我正在尝试在 Python 上用 Wand 编写一个自动化脚本,它通过一次一个字母地为图像编写标题来构建文本动画的帧。

问题是,当我使用标题命令(此处的文档 http://docs.wand-py.org/en/0.4.4/wand/image.html)写一个字母时,它写了一个巨大的字母,而当我写下整个文本时,它在图像中很合适。

我想到了一个可能的解决方案:将第一个字母写成彩色,其余字母透明并循环显示,但据我所知,caption 命令无法处理彩色文本。

如果有人可以建议我另一种选择,我将不胜感激。我可以使用 draw.text,但据我所知,它不会自动计算何时进入下一行...

我的代码如下所示:

imgname = random.choice(os.listdir('/home/gionny/Downloads/HighResImg'))
text = 'Hello, world! This is a slightly longer sentence.'
fontname = random.choice(os.listdir('/home/gionny/Downloads/font'))
with Image(filename='HighResImg/'+imgname) as i:    
    font = Font(path = 'font/'+fontname, color = Color('#fff'))
    textWidth = i.width*2/3
    textHeight = i.height*2/3
    offsetLeft = (i.width - textWidth)/2
    offsetTop = (i.height - textHeight)/2
    with Image(filename='logo.gif') as l:
        l.resize(80,80)
        l.transparentize(0.7)
        with Drawing() as draw:
            draw.composite(operator='atop', left=i.width-90, top=i.height-90, width=l.width, height=l.height, image=l)
            for c in range(0, len(text)):
                caption = i.caption(text = text[c], left = offsetLeft, top = offsetTop, width=textWidth, height=textHeight, font = font, gravity = 'center')
                print(caption)
                cl = i.clone()
                cl.format = 'jpeg'
                cl.save(filename='Text/text'+str(c)+'.jpg')
                cl.destroy()

If someone could suggest me another option I would be grateful. I could use draw.text, however that doesn't automatically calculate when to go on the next line as far as I know...

没有捷径可走,您负责计算每次迭代的 x,y 坐标。 特别是使用随机拉出的混合字体时。

已经为这种事情提供了方法wand.drawing.Drawing.get_font_metrics。只需保留一个累加器并在每次迭代时更新。

from wand.image import Image
from wand.color import Color
from wand.drawing import Drawing


with Image(width=400, height=250, background=Color("skyblue")) as background:
    leftOffset = 35  # <= Starting position.
    topOffset = background.height/2;
    for letter in "Hello World":
        with Drawing() as ctx:
            ctx.font = "TimesNewRoman"
            ctx.font_size = 64.0
            metrics = ctx.get_font_metrics(background, letter)
            ctx.text(leftOffset, int(topOffset+metrics.text_height/4), letter)
            with Image(width=background.width,
                       height=background.height,
                       background=Color("transparent")) as frame:
                ctx.draw(frame)
                background.sequence.append(frame)
            leftOffset += int(metrics.text_width)  # <= Adjust for next iteration.
    background.save(filename="output.gif")

现在重复下一行过程,如果 leftOffset 大于 canvas 宽度,只需将 topOffset 增加字体规格 text_height