绘制文本时 Pillow 图像的隐式像素密度是多少?

Ant*_*ony 1 python typography image python-imaging-library python-3.x

我正在尝试使用 python 中的 Pillow查找某些文本的大小(以磅为单位) 。据我了解,以磅为单位的字体大小对应于目标显示器或表面上的实际物理英寸,每英寸 72 点。当我使用 Pillow 的textsize方法时,我可以找到以给定字体大小(以磅为单位)呈现的某些文本的像素大小,但不知道如何返回基于英寸的坐标系,因为我没有(并且无法设置)图像的像素密度:

from PIL import Image, ImageFont, ImageDraw
image = Image.new('RGBA', (400, 300), (255, 255, 255))
font = ImageFont.truetype('/Library/Fonts/Arial.ttf', 16)
image.info['dpi'] = 100
print( ImageDraw.Draw(image).textsize('Loreum ipsum', font=font) )
image.info['dpi'] = 1000
print( ImageDraw.Draw(image).textsize('Loreum ipsum', font=font) )
Run Code Online (Sandbox Code Playgroud)

将打印

(101, 18)
(101, 18)
Run Code Online (Sandbox Code Playgroud)

如何获得给定文本的大小(以磅为单位) ?

小智 5

长话短说

没有隐式像素密度,因为 Pillow 文档不正确。当您创建字体时,您指定的size单位是像素,尽管 Pillow 文档说它是以磅为单位的。它实际上以像素为单位执行所有这些操作。

更多详情

Pillow 的文档ImageFont.truetype说,size争论是以点为单位的。但是,查看该模块的源代码ImageFont,它将size参数传递给core.getfont.

self.font = core.getfont(
    font, size, index, encoding, layout_engine=layout_engine
)
Run Code Online (Sandbox Code Playgroud)

该调用最终会导致FT_Set_Pixel_Sizes对 FreeType 库提供的 的调用。此调用转发给定的size、未修改的。

error = FT_Set_Pixel_Sizes(self->face, 0, size);
Run Code Online (Sandbox Code Playgroud)

各州的文件FT_Set_Pixel_Sizes

FT_EXPORT( FT_Error )
  FT_Set_Pixel_Sizes( FT_Face  face,
                      FT_UInt  pixel_width,
                      FT_UInt  pixel_height );
Run Code Online (Sandbox Code Playgroud)

调用 FT_Request_Size 请求标称尺寸(以像素为单位)。

face目标面部对象的句柄。

pixel_width标称宽度,以像素为单位。

pixel_height标称高度,以像素为单位。

因此,实际上这里根本不涉及物理距离,并且没有假设的 DPI 或ImageFont.truetypeImageDraw.textsize尽管 Pillow 文档具有误导性。一切都以像素为单位,因此不需要 DPI。

旁注:您可能会注意到您请求的尺寸 (16) 并不完全等于您返回的尺寸 (18),但 FreeType 提到您请求的尺寸不一定是您获得的尺寸,并且可以自行决定字体本身。