大约是Python中文本字符串的宽度?

大约是Python中文本字符串的宽度?,python,fonts,Python,Fonts,使用Python如何估计给定文本字符串的字体宽度 我正在寻找一个原型功能,类似于: def getApproximateFontWidth(the_string, font_name="Arial", font_size=12): return ... picas or pixels or something similar ... 我不是在寻找非常严格的东西,近似值就可以了 这样做的动机是,我在我的webapp后端生成一个截断字符串,并将其发送到前端进行显示。大多数情况下,字符串都是小

使用Python如何估计给定文本字符串的字体宽度

我正在寻找一个原型功能,类似于:

def getApproximateFontWidth(the_string, font_name="Arial", font_size=12):
   return ... picas or pixels or something similar ...
我不是在寻找非常严格的东西,近似值就可以了


这样做的动机是,我在我的webapp后端生成一个截断字符串,并将其发送到前端进行显示。大多数情况下,字符串都是小写的,但有时字符串都是大写的,这使得字符串非常宽。如果绳子没有正确固定,看起来很难看。我想知道根据字符串的近似宽度截断多少字符串。如果减少10%,这没什么大不了的,这是一个装饰性的功能。

您可以使用PIL渲染带有文本的图像,然后确定生成的图像宽度


我使用了一个库来实现这一点,但它需要pygame:
请看下面的sizeString

是我的简单解决方案,它可以让您获得80%的准确度,非常适合我的目的。它只适用于Arial,并且假定字体为12磅,但它可能也与其他字体成比例

def getApproximateArialStringWidth(st):
    size = 0 # in milinches
    for s in st:
        if s in 'lij|\' ': size += 37
        elif s in '![]fI.,:;/\\t': size += 50
        elif s in '`-(){}r"': size += 60
        elif s in '*^zcsJkvxy': size += 85
        elif s in 'aebdhnopqug#$L+<>=?_~FZT' + string.digits: size += 95
        elif s in 'BSPEAKVXY&UwNRCHD': size += 112
        elif s in 'QGOMm%W@': size += 135
        else: size += 50
    return size * 6 / 1000.0 # Convert to picas
渲染时,这些字符串的宽度大致相同:

那只敏捷的棕色狐狸跳过了树


棕色狐狸快速跳跃

Ya,这将是准确而严格的方法,但我希望避免渲染图像。我将自己写下这篇文章并在这里发布。使用加载字体的
getsize
方法,例如
font.getsize('spam')
。它返回一个以像素为单位的元组
(宽度、高度)
。看起来它将呈现文本,这是我想要避免的。为什么对您来说,这比PIL的
font.getsize('spam')
?PIL是一个很大的库,它还需要加载字体文件。我只是在寻找一个近似值,如果不需要的话,我不想依赖PIL。PIL肯定会更准确,可能对非ascii字符更有效,但就我而言,近似值很好。在你的问题中列出这些标准会很有用。这个标准定义有任何链接吗?你可以在前端使用还是?理论上是的,这可以在前端完成,但与全文相比,显示的文本量非常小。我只呈现了一个片段(一行或两行),可能有很多页(可能有几百页)。如果可能的话,我宁愿把它放在后端。文本溢出:对于短文本,省略号看起来很难看。印地语、藏语、泰语、韩语和汉语是固定宽度的,拉丁语和西里尔语应该以字符形式呈现到快速查找表中,然后您可以使用该查找表来计算任何字符串的宽度。由于自动连字,阿拉伯语和乌尔都语应该更加复杂。
def truncateToApproximateArialWidth(st, width):
    size = 0 # 1000 = 1 inch
    width = width * 1000 / 6 # Convert from picas to miliinches
    for i, s in enumerate(st):
        if s in 'lij|\' ': size += 37
        elif s in '![]fI.,:;/\\t': size += 50
        elif s in '`-(){}r"': size += 60
        elif s in '*^zcsJkvxy': size += 85
        elif s in 'aebdhnopqug#$L+<>=?_~FZT' + string.digits: size += 95
        elif s in 'BSPEAKVXY&UwNRCHD': size += 112
        elif s in 'QGOMm%W@': size += 135
        else: size += 50
        if size >= width:
            return st[:i+1]
    return st
>> width = 15
>> print truncateToApproxArialWidth("the quick brown fox jumps over the lazy dog", width) 
the quick brown fox jumps over the
>> print truncateToApproxArialWidth("THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG", width) 
THE QUICK BROWN FOX JUMPS