使用Python PIL库获取某个字体渲染后的文本的宽高(应用于检测翻译后的文本是否长度过长)

Posted 林新发

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Python PIL库获取某个字体渲染后的文本的宽高(应用于检测翻译后的文本是否长度过长)相关的知识,希望对你有一定的参考价值。

一、前言

嗨,大家好,我是新发。
最近有这么个需求,有一份中译英的文件,比如长这样:
在这里插入图片描述
我们需要检测翻译成英文后的文本长度是否过长。这里并不是简单的取字符串的字符个数进行计算,而是需要应用某个字体渲染后的文本长度。
比如我们使用微软雅黑字体渲染第一个中英文本,要取的是在微软雅黑字体下的中文文本的宽度与英文文本的宽度。
在这里插入图片描述
为什么需要做这样的检测呢?因为实际场合中,这些文本可能要作为电影字幕或者是软件翻译,所以要保证文本宽度不能过宽,否则可能文本会超过屏幕或者界面边缘。我们假设翻译后的英文文本宽度如果超过中文文本的宽度的200%就是过宽的,需要回炉精简。
好了,大家退后,我要开始展示才艺了。

二、python脚本:PIL库检测某个字体渲染后的文本的宽高

最终,我写的python脚本如下。
因为需要读取excel文件,我用了openpyxl库,使用方法可以参见我之前写的这篇文章:《教你使用python读写Excel表格(增删改查操作),使用openpyxl库》
然后需要获取某个字体渲染后的文本宽高,这里我用了PILPython Image Library)图像库,将文字绘制到画布上之后,获取经过修剪的边界框,即可计算出渲染后的文本宽高了。
下面的python代码保存为check_text_size.py,统计目录中放微软雅黑字体(msyh.ttc)和翻译的excel文件(中译英.xlsx)。
在这里插入图片描述

import openpyxl
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

fontsize=26
white = (255,255,255)

def get_font_render_size(text):
    canvas = Image.new('RGB', (2048,2048))
    draw = ImageDraw.Draw(canvas)
    monospace = ImageFont.truetype("msyh.ttc", fontsize)
    draw.text((0, 0), text, font=monospace, fill=white)
    bbox = canvas.getbbox()
    # 宽高
    size = (bbox[2] - bbox[0], bbox[3] - bbox[1])
    return size

# 遍历excel的行
def walk_excel_rows(excel_file):
    book = openpyxl.load_workbook(excel_file)
    sheet = book['Sheet1']
    for one_row in sheet.rows:
        yield (one_row[0].value, one_row[1].value)
    book.close()


if '__main__' == __name__:
    print('输出翻译后文本过长的句子')
    for (zh_text, en_text) in walk_excel_rows(u'中译英.xlsx'):
        zh_render_size = get_font_render_size(zh_text)
        en_render_size = get_font_render_size(en_text)
        if en_render_size[0] > zh_render_size[0] * 1.8:
            print(zh_text + ':' + en_text, '宽度比: %.2f' %(en_render_size[0]/zh_render_size[0]))
    print('检测完毕')

运行结果如下:

============ RESTART: E:\\python_pro\\check_font\\check_lbl_width.py ============
输出翻译后文本过长的句子
这幅画是名副其实的杰作。:The painting is a masterpiece in the truest sense of the word. 宽度比: 2.60
检测完毕

扫描出“这幅画是名副其实的杰作”。这句的翻译英文文本过长了,那我们重新精简的翻译一下:
This painting is a veritable masterpiece
在这里插入图片描述
再次运行,所有句子都通过了。

三、python PIL库知识点补充

1、安装PIL库

通过pip命令进行安装。

pip install Pillow

如果在pythonimport PIL没有报错,则说明安装PIL库成功。
在这里插入图片描述

2、创建画布

from PIL import Image

# 创建画布,第二个参数是画布尺寸
canvas = Image.new('RGBA', (128,128))
# 显示画布
canvas.show()

运行效果:
在这里插入图片描述

3、创建画笔

draw = ImageDraw.Draw(画布)

例:

from PIL import Image
from PIL import ImageDraw

# 创建画布
canvas = Image.new('RGBA', (128,128))
# 创建画笔
draw = ImageDraw.Draw(canvas)

# 显示画布
canvas.show()

4、画线

draw.line((起点x, 起点y, 终点x, 终点y), 颜色)

例:

from PIL import Image
from PIL import ImageDraw

# 创建画布
canvas = Image.new('RGBA', (128,128))
# 创建画笔
draw = ImageDraw.Draw(canvas)
# 画线
draw.line((20, 30, 100, 90), 'cyan')
# 显示画布
canvas.show()

运行效果:
在这里插入图片描述

5、画矩形

draw.rectangle((左上角x, 左上角y, 右下角x, 右下角y), 填充颜色, 描边颜色)

例:

from PIL import Image
from PIL import ImageDraw

# 创建画布
canvas = Image.new('RGBA', (128,128))
# 创建画笔
draw = ImageDraw.Draw(canvas)
# 画矩形
draw.rectangle((10, 20, 100, 80), 'green', 'red')
# 显示画布
canvas.show()

运行效果:
在这里插入图片描述

6、画弧线

draw.arc((左上角x, 左上角y, 右下角x, 右下角y), 起始角度, 结束角度, 描边颜色)

例:

from PIL import Image
from PIL import ImageDraw

# 创建画布
canvas = Image.new('RGBA', (128,128))
# 创建画笔
draw = ImageDraw.Draw(canvas)
# 画弧线
draw.arc((20, 50, 100, 90), 0, 360, 'yellow')
# 显示画布
canvas.show()

运行效果:
在这里插入图片描述

7、画椭圆(或圆)

draw.ellipse((左上角x, 左上角y, 右下角x, 右下角y), 填充颜色, 描边颜色)

例:

from PIL import Image
from PIL import ImageDraw

# 创建画布
canvas = Image.new('RGBA', (128,128))
# 创建画笔
draw = ImageDraw.Draw(canvas)
# 画椭圆
draw.ellipse((20, 20, 100, 110), 'yellow', 'red')
# 显示画布
canvas.show()

运行效果:
在这里插入图片描述

8、写字

font = ImageFont.truetype(字体文件, 字体大小, 编码)
draw.text((坐标x, 坐标y), 文本, 颜色, font)

例:

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

# 创建画布
canvas = Image.new('RGBA', (128,128))
# 创建画笔
draw = ImageDraw.Draw(canvas)
# 写字
font = ImageFont.truetype("msyh.ttc", 30, encoding="utf-8")
draw.text((20, 20), u'林新发', 'white', font)
# 显示画布
canvas.show()

运行效果:
在这里插入图片描述

四、结束语

完毕。
博主是Unity3D游戏工程师,喜欢Unity的同学,不要忘记点击关注,如果有什么Unity相关的技术难题,也欢迎留言或私信~

以上是关于使用Python PIL库获取某个字体渲染后的文本的宽高(应用于检测翻译后的文本是否长度过长)的主要内容,如果未能解决你的问题,请参考以下文章

Python 图像库 - 文本渲染

使用 PIL 绘制多语言文本

用 PIL 绘制粗体/斜体文本?

django项目验证码(PIL库实现)

如何将非抗锯齿字体渲染到内部图像?

使用 PIL 在 OpenCV Python 中更改字体系列