Python3 PIL使用font字体错误

在项目中试用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,保存代码后重启程序,然后刷新一下页面,可以看到二维码图片出现了。
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丁爸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值