Python PIL生成证书时遭遇OSError: cannot open resource错误的排查求助
解决PIL无法加载自定义字体的OSError问题
你的错误 OSError: cannot open resource 核心原因是PIL找不到指定的字体文件,结合你的运行环境(Linux系统,路径显示/home/rohit07),问题主要出在路径分隔符不兼容和硬编码路径的可靠性上,下面是一步步的解决方法:
1. 修复路径分隔符问题
你在脚本里用了Windows风格的路径分隔符\,但Linux系统默认使用/作为路径分隔符,直接用\会导致系统无法识别路径。可以直接替换分隔符:
font = ImageFont.truetype("./Dancing_Script/DancingScript-VariableFont_wght.ttf", 150)
更稳妥的方式是用Python内置的os.path模块构建跨平台路径,这样不管在Windows还是Linux环境下都能正常工作,还能避免相对路径的歧义:
import os # 获取当前脚本所在文件夹的绝对路径,再拼接字体文件路径 font_path = os.path.join(os.path.dirname(__file__), "Dancing_Script", "DancingScript-VariableFont_wght.ttf") font = ImageFont.truetype(font_path, 150)
2. 验证字体文件的实际位置
虽然你说检查过路径,但Linux系统是大小写敏感的,建议在终端手动确认文件是否存在:
# 先切换到脚本所在的文件夹 cd /home/rohit07/[你的脚本存放目录] # 检查字体文件是否存在 ls -l ./Dancing_Script/DancingScript-VariableFont_wght.ttf
如果输出No such file or directory,说明文件夹结构、文件名大小写或者拼写有误,比如是否把Dancing_Script写成了dancing_script。
3. 检查文件权限
如果文件确实存在但仍报错,可能是脚本没有读取字体文件的权限,执行以下命令赋予读取权限:
chmod +r ./Dancing_Script/DancingScript-VariableFont_wght.ttf
4. 脚本优化(可选)
你的脚本里重复加载了两次字体文件,既浪费IO资源也容易出错,可以提前加载好两种字号的字体,再按需使用:
import os from PIL import Image, ImageFont, ImageDraw import pandas as pd def main(): print("Initializing Script!") # 提前构建字体路径并加载两种字号的字体 font_dir = os.path.join(os.path.dirname(__file__), "Dancing_Script") font_150 = ImageFont.truetype(os.path.join(font_dir, "DancingScript-VariableFont_wght.ttf"), 150) font_130 = ImageFont.truetype(os.path.join(font_dir, "DancingScript-VariableFont_wght.ttf"), 130) names = pd.read_csv('dummy_names.csv') for i,row in names.iterrows(): name = f"{row['FName']} {row['LName']}".title() empty_img = Image.open("empty-cert.png") W,H = empty_img.size # 先尝试150号字体 w, h = font_150.getsize(name) width = (W - w)/2 height = (H - h)/2 - 50 current_font = font_150 # 如果字体过大,切换到130号并调整位置 if W % w >= 2: current_font = font_130 w, h = current_font.getsize(name) width = (W - w)/2 +75 height = (H - h)/2 -10 image_editable = ImageDraw.Draw(empty_img) image_editable.multiline_text((width,height), name, (35, 57, 75), font=current_font) empty_img.save(f"{name.replace(' ', '_')}.jpg") if i % 50 == 0: print(f'Processed {i} Rows') print("Process Complete!") if __name__ == "__main__": main()
按照上面的步骤操作,应该就能解决找不到字体文件的问题了。
内容的提问来源于stack exchange,提问作者Rohit Dalvi
相关产品推荐
相关产品推荐

