Python3 PIL使用font字体错误

2022-08-01,,,,

在项目中试用PIL生成验证码时,在win10环境下安装PIL,项目运行时能正常生成二维码,在Centos7环境下报错:

File "./ClothStore/captcha/captcha.py", line 123, in <listcomp>
    for size in font_sizes or (65, 70, 75)])
  File "/home/ClothStore/venv/lib/python3.7/site-packages/PIL/ImageFont.py", line 655, in truetype
    return freetype(font)
  File "/home/ClothStore/venv/lib/python3.7/site-packages/PIL/ImageFont.py", line 652, in freetype
    return FreeTypeFont(font, size, index, encoding, layout_engine)
  File "/home/ClothStore/venv/lib/python3.7/site-packages/PIL/ImageFont.py", line 194, in __init__
    font, size, index, encoding, layout_engine=layout_engine
OSError: cannot open resource

本文介绍如何解决该过程的方法。

1. 确定错误类型

根据错误信息,OSError: cannot open resource发现应该是资源文件没有找到,用vim打开文件/home/ClothStore/venv/lib/python3.7/site-packages/PIL/ImageFont.py,更加错误提示跳转到194行,

if isPath(font):
            if sys.platform == "win32":
                font_bytes_path = font if isinstance(font, bytes) else font.encode()
                try:
                    font_bytes_path.decode("ascii")
                except UnicodeDecodeError:
                    # FreeType cannot load fonts with non-ASCII characters on Windows
                    # So load it into memory first
                    with open(font, "rb") as f:
                        load_from_bytes(f)
                    return
            self.font = core.getfont(
                font, size, index, encoding, layout_engine=layout_engine
            )
        else:
            load_from_bytes(font)

错误信息在下面这一行,说明字体资源文件没找到,定位的问题是:资源文件缺失

self.font = core.getfont(font, size, index, encoding,layout_engine=layout_engine)

再用vim打开报错文件./ClothStore/captcha/captcha.py,跳转到错误行123,

class Captcha(object):
    def __init__(self):
        self._bezier = Bezier()
        self._dir = os.path.dirname(__file__)
        # self._captcha_path = os.path.join(self._dir, '..', 'static', 'captcha')

    @staticmethod
    def instance():
        if not hasattr(Captcha, "_instance"):
            Captcha._instance = Captcha()
        return Captcha._instance

    def initialize(self, width=200, height=75, color=None, text=None, fonts=None):
        # self.image = Image.new('RGB', (width, height), (255, 255, 255))
        self._text = text if text else random.sample(string.ascii_uppercase + string.ascii_uppercase + '3456789', 4)
        self.fonts = fonts if fonts else \
            [os.path.join(self._dir, 'fonts', font) for font in ['SIMYOU.TTF']]
        self.width = width
        self.height = height
        self._color = color if color else self.random_color(0, 200, random.randint(220, 255))

    @staticmethod
    def random_color(start, end, opacity=None):
        red = random.randint(start, end)
        green = random.randint(start, end)
        blue = random.randint(start, end)
        if opacity is None:
            return red, green, blue
        return red, green, blue, opacity

错误信息在下面这行,我们发现这里用到字体资源文件SIMYOU.TTF,可能在当前Centos7系统里面没有

self.fonts = fonts if fonts else [os.path.join(self._dir, 'fonts', font) for font in ['SIMYOU.TTF']]

我们用命令查找一下,find / -name SIMYOU.TTF

[root@6c53424032ec ClothStore]# find / -name SIMYOU.TTF
[root@6c53424032ec ClothStore]# 

没有找到SIMYOU.TTF字体信息,现在可以确定是字体资源文件缺失导致报错提示信息。

2. 解决问题

我们在系统字体库路径/usr/share/fonts/gnu-free下选一下字体,

[root@6c53424032ec ClothStore]# ls /usr/share/fonts/gnu-free/
FreeMonoBoldOblique.ttf  FreeMono.ttf             FreeSansOblique.ttf      FreeSerifBold.ttf        .uuid                    
FreeMonoBold.ttf         FreeSansBoldOblique.ttf  FreeSans.ttf             FreeSerifItalic.ttf      
FreeMonoOblique.ttf      FreeSansBold.ttf         FreeSerifBoldItalic.ttf  FreeSerif.ttf  

我们把SIMYOU.TTF换成FreeMono.ttf,保存代码后重启程序,然后刷新一下页面,可以看到二维码图片出现了。

本文地址:https://blog.csdn.net/yyt593891927/article/details/107463612

《Python3 PIL使用font字体错误.doc》

下载本文的Word格式文档,以方便收藏与打印。