用PIL裁剪字体

2024-09-29 21:30:32 发布

您现在位置:Python中文网/ 问答频道 /正文

这个图像是用PIL创建的。看到这张图中g和y是怎么被切断的吗?我怎样才能防止这种情况?在

http://img109.imageshack.us/img109/8874/screenshotep.png

创建此图像的代码非常直接(缩写):

import Image, ImageDraw, ImageFont

im = Image.new("RGBA", (200, 200), 'white')
draw = ImageDraw.Draw(im)

font = ImageFont.truetype("VeraSe.ttf", 12)

draw.text(
           (1, 1),
           " %s: " % "ggjyfFwe__",
           font=font,
           fill='black'
)

draw.text(
           (1, 30),
           " %s" % 15,
           font=font,
           fill='black'
)

im.show()

我尝试了几种不同的字体,但总是被剪掉。令人惊讶的是,谷歌搜索“PIL-font-clipping”只返回很少有用的点击。。。我在ubuntu9.10上使用python2.6.4和pil1.1.6


Tags: text图像imagehttppil情况fillblack
3条回答

对于某些字体,我无法使用到目前为止提到的方法来解决这个问题,所以我最终使用aggdraw作为PIL文本绘制方法的透明替代。在

重写为aggdraw的代码如下所示:

import Image
import aggdraw

im = Image.new("RGBA", (200, 200), 'white')
draw = aggdraw.Draw(im)

# note that the color is specified in the font constructor in aggdraw
font = aggdraw.Font((0,0,0), "VeraSe.ttf", size=12, opacity=255)

draw.text((1, 1), " %s: " % "ggjyfFwe__", font) # no color here
draw.text((1, 30), " %s" % 15, font)

draw.flush() # don't forget this to update the underlying PIL image!

im.show()

这是这个老问题的最新答案。在

问题似乎是PIL和Pillow将剪辑呈现文本的边缘。这通常显示在尾随的宽字符和decenter上(比如'y's)。这也可以出现在一些字体的顶部。这至少已经有十年了。无论调用text()的图像的大小,都会发生这种情况。冲突似乎是选择边界矩形为“字体大小*数字字符”而不是“我实际需要呈现的任何内容”,这在堆栈的深处出现(_imagingft.c)。解决这个问题会导致其他问题,比如逐字排列文本。在

一些解决方案包括:

  • 在字符串末尾附加一个空格。im.text(xy, my_text + ' ', ...)
  • 对于高度问题,获取文本的宽度(font.getsize()),然后呈现文本,再加上一个良好的升序和降序,将呈现的文本剪切到第一个报告的宽度和第二个实际高度。在
  • 使用其他库,如AggDrawpyvips。在

这在各种问题fonts clipping with PILPIL cuts off top of lettersProperly render text with a given font in Python and accurately detect its boundaries中都有引用。这些问题涉及相同的基本问题,但不是重复的

这个“bug”在2012年仍然存在,使用Ubuntu11.10。Fontsize 11、12、13和15完全剪切下划线。在

#!/usr/bin/env python
""" demonstrates clipping of descenders for certain font sizes """
import Image, ImageDraw, ImageFont
fontPath = "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf"
im = Image.new('L', (256, 256))
ys=15
for i in range(10,21):
    fh = ImageFont.truetype(fontPath, i)
    sometext="%dgt_}" % (i)
    ImageDraw.Draw(im).text((10, ys ),sometext , 254, fh)
    ys+=i+5
im.show()

相关问题 更多 >

    热门问题