使用PyInstaller打包含barcode库的Python程序时生成条码报错
问题:barcode库配合PyInstaller打包后运行报错:OSError: cannot open resource
我用barcode库写了个生成条码并保存为PNG的Python程序,在Python解释器里跑完全正常,但用PyInstaller打包成可执行文件后运行报错。
错误信息:
File "tkinter/__init__.py", line 1948, in __call__ File "Bachmaier.py", line 668, in save_selection File "Barcode_generator.py", line 13, in generate_barcodes barcode_image = code128.render(writer_options={"font_size": 1, "text_distance": 1}) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "barcode/codex.py", line 255, in render File "barcode/base.py", line 100, in render File "barcode/writer.py", line 269, in render File "barcode/writer.py", line 440, in _paint_text File "PIL/ImageFont.py", line 791, in truetype File "PIL/ImageFont.py", line 788, in freetype File "PIL/ImageFont.py", line 226, in __init__ OSError: cannot open resource
相关代码片段:
import os from barcode import Code128 from barcode.writer import ImageWriter def generate_barcodes(stl_names, path): barcodes = [] # To store the barcode image paths for name in stl_names: barcode_name = f"{name}" code128 = Code128(barcode_name, writer=ImageWriter()) # Generate the barcode as a PIL image barcode_image = code128.render(writer_options={"font_size": 1, "text_distance": 1}) # Save the barcode image as a PNG file barcode_file_path = os.path.join(path, f"{barcode_name}.png") barcode_image.save(barcode_file_path, "PNG") barcodes.append(barcode_file_path) return barcodes
我没在代码里显式用字体,已经试过用PyInstaller的--add-data打包资源,但问题还在。想知道错误原因、解决方法,还有用barcode库配合PyInstaller打包的注意事项。
错误原因
barcode库的ImageWriter默认会调用PIL的ImageFont.truetype加载系统默认字体,但PyInstaller打包后,程序无法自动定位系统字体路径,且默认字体没有被打包进可执行文件的运行环境,导致加载字体资源失败,抛出OSError: cannot open resource。
解决方法
方法1:指定明确的字体路径
- 找一个本地TTF字体文件(比如系统自带的
Arial.ttf或simhei.ttf),放到项目目录中。 - 修改代码,在
render的writer_options里添加font_path参数:
# 假设字体文件是项目根目录下的arial.ttf font_path = os.path.join(os.path.dirname(__file__), "arial.ttf") barcode_image = code128.render(writer_options={ "font_size": 1, "text_distance": 1, "font_path": font_path })
- 打包时用
--add-data把字体文件包含进去:
# Windows系统 pyinstaller --add-data "arial.ttf;." your_script.py # macOS/Linux系统 pyinstaller --add-data "arial.ttf:." your_script.py
方法2:禁用条码下方的文本显示
如果不需要条码下方的文字,可以直接关闭文本渲染,跳过字体加载步骤:
barcode_image = code128.render(writer_options={ "font_size": 1, "text_distance": 1, "write_text": False # 关闭文本显示 })
打包注意事项
- 显式打包依赖资源:
barcode依赖PIL处理图片,PyInstaller无法自动识别PIL的字体依赖,必须手动指定需要打包的字体文件。 - 动态处理路径:打包后程序的运行路径会变化,要用
os.path.dirname(__file__)或sys._MEIPASS获取打包后的资源路径,避免硬编码路径。 - 跨平台测试:不同系统的默认字体路径和名称不同,跨平台打包时最好自带字体文件,避免依赖系统字体。
- 查看打包日志:如果仍有资源缺失问题,用
pyinstaller --log-level DEBUG your_script.py查看日志,确认资源是否被正确包含。
内容的提问来源于stack exchange,提问作者amarinelloa
相关产品推荐
相关产品推荐

