【问题标题】:ImageFont's getsize() does not get correct text size?ImageFont 的 getsize() 没有得到正确的文本大小?
【发布时间】:2023-04-06 09:11:01
【问题描述】:

我使用以下两种方法为.ttf字体文件生成文本预览图像

PIL 方法:

def make_preview(text, fontfile, imagefile, fontsize=30):
    try:
        font = ImageFont.truetype(fontfile, fontsize)
        text_width, text_height = font.getsize(text)
        img = Image.new('RGBA', (text_width, text_height))
        draw = ImageDraw.Draw(img)
        draw.text((0, 0), text, font=font, fill=(0, 0, 0))
        return True
    except:
        return False

ImageMagick 方法:

def make_preview(text, fontfile, imagefile, fontsize=30):
    p = subprocess.Popen(['convert', '-font', fontfile, '-background',
            'transparent', '-gravity', 'center', '-pointsize', str(fontsize),
            '-trim', '+repage', 'label:%s' % text, image_file])
    return p==0

这两种方法大部分时间都能创建正确的预览图像,但在极少数情况下(

示例字体和预览:

HANFORD.TTF http://download.appfile.com/HANFORD.png

NEWTOW.TTF http://download.appfile.com/NEWTOW.png

MILF.TTF http://download.appfile.com/MILF.png

SWANSE.TTF http://download.appfile.com/SWANSE.png

我查看了 ImageMagick 的文档,并在 http://www.imagemagick.org/Usage/text/#overflow 找到了这个问题的解释。

是否有可能检测到这样的文本溢出并按照我们的预期绘制适合画布的文本?

【问题讨论】:

    标签: python fonts imagemagick python-imaging-library


    【解决方案1】:

    不是编程解决方案,但是当我重新生成您的问题时,它只发生在您的字体上(其他字体,如 Arial 完全没有问题),所以我已经修复了您的字体文件(通过更改上升/体面指标)。你可以下载here

    对不起,Hanford Script Font,它并不完美,你看,高度似乎还可以,但左侧没有被绘制,它超出了我的理解。

    更新:关于 Hanford 字体,这是一个变通方法,在文本中传递额外的空间,如 "Handford Script",然后像 @ 一样裁剪图像中的额外空间987654327@

    alt text http://img64.imageshack.us/img64/1903/hanfordfontworkaround.jpg

    UPDATE2:我必须在 Image.New 中传递 color=(255,255,255) 才能获得白色背景上的黑色文本

    img = Image.new('RGBA', (text_width, text_height),color=(255,255,255))
    

    【讨论】:

    • 如何修改指定字体的上升/体面度量?是否需要按字体手动重新计算?
    • 由于版权问题,我认为最好将字体保持原样并在更大的画布上绘制文本然后裁剪它。但是您的方法适用于个人使用。谢谢你的建议。
    • 非常正确,但是您为什么先将它们公开下载?我会尽快删除我帖子中的下载链接。
    【解决方案2】:

    我曾经在 PHP 和 ImageMagick 中遇到过类似的问题。

    最后,我通过在一个非常大的画布上绘制文本来解决这个问题,然后使用 trim/auto-crop 函数修剪它,从而从图像上去除额外的空间。

    如果我正确理解您的预览功能,它实际上已经在这样做了:只需删除宽度和高度设置就足够了。

    【讨论】:

    • @Pekka,您的方法可能适用于 IM,但它会产生很大的开销,不仅修剪而且调整修剪后的图像大小以适合指定的画布尺寸。这不适用于 PIL。即使我创建更大的画布,它也总是绘制上述字体的上半部分。
    • 尝试将“label”命令放在 trim 和 repage 命令之前,应该可以。开销,我无能为力。
    【解决方案3】:

    在这种情况下,只需指定 ImageMagick 以使用更大的画布大小和固定的字体大小,它会以指定的点大小绘制文本,同时保持其完整性。

    def make_preview(text, fontfile, imagefile, fontsize=30):
        p = subprocess.call(['convert', '-font', fontfile, '-background', 
            'transparent', '-gravity', 'center', '-size', '1500x300',
            '-pointsize', str(fontsize),  '-trim', '+repage', 'label:%s' % text, image_file]) 
        return p==0 
    

    如果您需要将文本放入指定的画布而不是使用固定点大小,您可能需要在创建输出图像后调整其大小。

    PIL 不能很好地绘制奇异字体,无论您指定什么磅值来加载字体,它总是会溢出输出图像之外的文本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-21
      • 1970-01-01
      • 2016-01-23
      • 1970-01-01
      • 1970-01-01
      • 2014-08-12
      • 1970-01-01
      • 2019-07-02
      相关资源
      最近更新 更多