Python中如何使用Pyinstaller打包并添加图片音频等资源文件

毕业设计用 pyqt 做的一个 UI, 三个问题: 1.缺少 api-ms-win-crt-*.dll
2.添加-i 参数添加程序图标 显示错误 OSError: [Errno 22] Invalid argument 3.无法添加其他资源

那位大佬指导下,感激不尽,块交论文拉 /(ㄒoㄒ)/~~


Python中如何使用Pyinstaller打包并添加图片音频等资源文件
7 回复

这是我之前用 pyqt5 写的一个爬虫程序 https://github.com/Hopetree/TMTools,这个里面就添加了 LOGO 还有其他图片效果,你自己看看

你在打包之前能运行成功吗?如果可以,你打包的方式会不会有问题?反正图片是要跟打包之后的程序放在一起的,图片并不能打包进 exe 中


在Python中使用Pyinstaller打包资源文件(如图片、音频)时,关键在于正确配置.spec文件或使用命令行参数来包含这些文件。核心思路是让Pyinstaller知道资源文件的位置,并在运行时能正确访问它们。

方法一:通过修改.spec文件(推荐)

  1. 首先生成spec文件:
pyinstaller --name=myapp your_script.py
  1. 编辑生成的myapp.spec文件,在Analysis部分添加datas列表:
a = Analysis(
    ['your_script.py'],
    pathex=[],
    binaries=[],
    datas=[('path/to/image.png', '.'), ('path/to/audio.mp3', '.')],  # 添加这行
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    noarchive=False,
)

格式:(源文件路径, 打包后目标文件夹).表示放在根目录。

  1. 使用spec文件重新打包:
pyinstaller myapp.spec

方法二:使用命令行参数

pyinstaller --add-data "path/to/image.png:." --add-data "path/to/audio.mp3:." your_script.py

Windows系统用分号:"path\to\image.png;."

代码中如何访问资源文件:

关键是要使用sys._MEIPASS来获取临时解压路径:

import sys
import os
from pathlib import Path

def resource_path(relative_path):
    """获取资源的绝对路径"""
    try:
        base_path = sys._MEIPASS  # PyInstaller创建的临时文件夹
    except AttributeError:
        base_path = os.path.abspath(".")
    
    return os.path.join(base_path, relative_path)

# 使用示例
image_path = resource_path("image.png")
audio_path = resource_path("audio.mp3")

# 然后正常使用这些路径
print(f"图片路径: {image_path}")
print(f"音频路径: {audio_path}")

完整示例:

假设项目结构:

myproject/
├── src/
│   ├── main.py
│   └── resources/
│       ├── icon.png
│       └── sound.mp3
└── build/
  1. main.py
import sys
import os
import pygame
from pathlib import Path

def resource_path(relative_path):
    """获取资源文件的正确路径"""
    try:
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")
    
    return os.path.join(base_path, relative_path)

def main():
    # 初始化pygame
    pygame.init()
    
    # 加载资源
    icon_path = resource_path("resources/icon.png")
    sound_path = resource_path("resources/sound.mp3")
    
    print(f"图标路径: {icon_path}")
    print(f"声音路径: {sound_path}")
    
    # 这里可以添加实际的图片/音频加载代码
    # image = pygame.image.load(icon_path)
    # sound = pygame.mixer.Sound(sound_path)
    
    pygame.quit()

if __name__ == "__main__":
    main()
  1. 打包命令:
pyinstaller --name=myapp --add-data "src/resources/*:resources" src/main.py
  1. 或者创建myapp.spec
# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

a = Analysis(
    ['src/main.py'],
    pathex=[],
    binaries=[],
    datas=[('src/resources/*', 'resources')],  # 所有资源文件放到resources文件夹
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)

pyz = PYZ(a.pure)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.datas,
    [],
    name='myapp',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)

总结:sys._MEIPASS获取路径,在spec文件或命令行中指定资源文件。

打包之前是可以的 pyinstaller --add-data=b.jpg;. --add-data=Dossier_Luffy_128px_1108222_easyicon.net.ico;. --ico=bb.jpg -w --clean Newstool.py
这是我执行的命令 然后错误不断,你打包的售后没有报错?

这个自己写个打包脚本就行了,除了 logo 其他不相关的资源文件直接通过脚本 copy 到 dist 的程序目录下去,缺少的文件通通 copy 过去

我不是用你这种命令添加的素材啊,打包方式看这个 http://www.cnblogs.com/gopythoner/p/6337543.html

只有程序的图标是通过命令添加的,其他的图片素材都是不需要添加的,只需要把放素材的文件跟图片放在一起就行了,程序运行会自动读取素材所在的地址调用的

添加-i 选项后就是这个错误:
38771 INFO: Updating icons from [‘bb.ico’] to C:\Users\ADMINI~1\AppData\Local\Temp\tmpijoxn4qa
Traceback (most recent call last):
File “C:\Users\Administrator\AppData\Local\Programs\Python\Python35\Scripts<a target=”_blank" href=“http://pyinstaller-script.py” rel=“nofollow noopener”>pyinstaller-script.py", line 9, in <module>
load_entry_point(‘PyInstaller==3.4.dev0+31785ca87’, ‘console_scripts’, ‘pyinstaller’)()
File “C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-packages\pyinstaller-3.4.dev0+31785ca87-py3.5.egg\PyInstaller<a target=”_blank" href=“http://main.py” rel=“nofollow noopener”>main.py", line 94, in run
run_build(pyi_config, spec_file, **vars(args))
File “C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-packages\pyinstaller-3.4.dev0+31785ca87-py3.5.egg\PyInstaller<a target=”_blank" href=“http://main.py” rel=“nofollow noopener”>main.py", line 46, in run_build
PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
File “C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-packages\pyinstaller-3.4.dev0+31785ca87-py3.5.egg\PyInstaller\building<a target=”_blank" href=“http://build_main.py” rel=“nofollow noopener”>build_main.py", line 791, in main
build(specfile, kw.get(‘distpath’), kw.get(‘workpath’), kw.get(‘clean_build’))
File “C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-packages\pyinstaller-3.4.dev0+31785ca87-py3.5.egg\PyInstaller\building<a target=”_blank" href=“http://build_main.py” rel=“nofollow noopener”>build_main.py", line 737, in build
exec(text, spec_namespace)
File “<string>”, line 26, in <module>
File “C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-packages\pyinstaller-3.4.dev0+31785ca87-py3.5.egg\PyInstaller\building<a target=”_blank" href=“http://api.py” rel=“nofollow noopener”>api.py", line 420, in init
self.postinit()
File “C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-packages\pyinstaller-3.4.dev0+31785ca87-py3.5.egg\PyInstaller\building<a target=”_blank" href=“http://datastruct.py” rel=“nofollow noopener”>datastruct.py", line 161, in postinit
self.assemble()
File “C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-packages\pyinstaller-3.4.dev0+31785ca87-py3.5.egg\PyInstaller\building<a target=”_blank" href=“http://api.py” rel=“nofollow noopener”>api.py", line 509, in assemble
icon.CopyIcons(tmpnm, self.icon)
File “C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-packages\pyinstaller-3.4.dev0+31785ca87-py3.5.egg\PyInstaller\utils\win32<a target=”_blank" href=“http://icon.py” rel=“nofollow noopener”>icon.py", line 177, in CopyIcons
return CopyIcons_FromIco(dstpath, [srcpath])
File “C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-packages\pyinstaller-3.4.dev0+31785ca87-py3.5.egg\PyInstaller\utils\win32<a target=”_blank" href=“http://icon.py” rel=“nofollow noopener”>icon.py", line 134, in CopyIcons_FromIco
for i, f in enumerate(icons):
File “C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-packages\pyinstaller-3.4.dev0+31785ca87-py3.5.egg\PyInstaller\utils\win32<a target=”_blank" href=“http://icon.py” rel=“nofollow noopener”>icon.py", line 107, in init
file.seek(e.dwImageOffset, 0)
OSError: [Errno 22] Invalid argument


不添加 -i 可以成功打包 尽管有很多警告信息

回到顶部