Python 绘制文字时枕头图像的隐式像素密度是多少?
我试图使用python中的Pillow来查找一些文本的大小(以点为单位)。据我所知,以点为单位的字体大小对应于目标显示器或表面上的实际物理英寸,每英寸72点。当我使用Pillow的Python 绘制文字时枕头图像的隐式像素密度是多少?,python,python-3.x,image,python-imaging-library,typography,Python,Python 3.x,Image,Python Imaging Library,Typography,我试图使用python中的Pillow来查找一些文本的大小(以点为单位)。据我所知,以点为单位的字体大小对应于目标显示器或表面上的实际物理英寸,每英寸72点。当我使用Pillow的textsize方法时,我可以找到以给定字体大小(以点为单位)渲染的某些文本的像素大小,但不知道如何返回以英寸为单位的坐标系,因为我没有(也无法设置)图像的像素密度: from PIL import Image, ImageFont, ImageDraw image = Image.new('RGBA', (400,
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) )
将打印
(101, 18)
(101, 18)
如何获得给定文本的点大小?图像没有“隐式”像素密度,只是像素数不同而已。以像素为单位测量的任何东西的大小将取决于显示设备的DPI或每英寸点数
例如,在100 DPI设备上,12个像素看起来是12/100或0.12英寸长。要将英寸转换为点,请将其乘以72。所以12像素→ 0.12英寸*72→ 8.84分。TL;DR
没有隐式像素密度,因为枕头文档不正确。创建字体时,您指定的是以像素为单位的大小
,即使枕头文档中说它是以点为单位的。它实际上是以像素为单位进行所有这些操作
更多细节
ImageFont.truetype
的枕头文档说明size
参数以点为单位。但是,查看ImageFont
模块的参数,它将size
参数传递给core.getfont
self.font = core.getfont(
font, size, index, encoding, layout_engine=layout_engine
)
调用FreeType库提供的对FT\u Set\u Pixel\u size
的调用。此调用转发给定的大小
,未经修改
error = FT_Set_Pixel_Sizes(self->face, 0, size);
FT\u设置的像素大小的状态
调用FT_Request_Size以请求标称大小(以像素为单位)
face
目标面对象的句柄
pixel\u width
标称宽度,单位为像素
像素高度
以像素为单位的标称高度
因此,这里实际上根本不涉及物理距离,而且无论是ImageFont.truetype
还是ImageDraw.textsize
,都没有假定的DPI,尽管有误导性的枕头文档。所有内容都以像素为单位,因此不需要DPI
侧注:您可能会注意到,您请求的大小(16)并不完全等于您要返回的大小(18),但FreeType提到,您请求的大小不一定是您得到的大小,这取决于字体本身。将点数乘以dpifactor@WayToDoor对,枕头在这里使用什么样的DPI系数?使用image.info['DPI']
来查找?@WayToDoor,一个新的图像将image.info
设置为{}
;没有dpi,这很好,因为图像没有dpi信息。如果设置了特定的DPI系数,则可以获得英寸数。如果你不知道,那么就没有办法得到图像的英寸数,因为这基本上是你在打印图像时设置的设置。我理解这一点,但我不理解字体如何计算文本的大小,以像素为单位,以点为单位,而不假设一些像素密度。字体不计算任何东西,它们实际上只是数据文件。正在使用的文本绘图软件(本例中为PIL/pillow)缩放字体文件中的字符形状数据,以便以指定的像素大小渲染每个字符/字形。ok,但ImageFont.truetype
方法采用大小
的点,这让我感到困惑。如何在点和像素之间建立对应关系?使用基本代数,您可以使用我的答案中描述的数学关系将点转换为像素(假设您知道或假设正在渲染的设备的某些DPI)。当然,我可以用一点代数计算出一些文本的大小(英寸),给出它的像素大小和显示密度。但我想知道,例如,当我告诉枕头画12点大小的文本时,它将使用多少像素来表示12点的距离。这是一个很棒的答案。感谢您深入了解这一点,并分享您的发现。我只是遇到了同样的问题。
FT_EXPORT( FT_Error )
FT_Set_Pixel_Sizes( FT_Face face,
FT_UInt pixel_width,
FT_UInt pixel_height );