解决pyinstaller GUI打包时无法打包图片问题

news2025/4/1 15:18:33

         当我们的python GuI在开发时。经常会用到图片作为背景,但是在打包后再启动GUI后却发现:原先调试时好端端的背景图片竟然不翼而飞或者直接报错。这说明图片没有被pyinstaller一起打包……

要解决这个问题很简单,就是更改图片的存储方式。

tkinter设置图片为背景

        首先,无论如何,要想导入并在GUI中显示图片,我们都要用到pilllow这个库

pillow获取方式

pip install pillow

正常显示思路

  1.  使用pillow Image下的open方法读取给定路径下(一般是同级目录,只需要指定文件名)的图片
  2.  使用pillow的ImageTk(专门用作于tkinter交互的图像处理工具)将其转换为tkinter类型图片
  3.  在tkinter中创建一个和窗口一样大的canvas将image传入作为背景图片

代码

import tkinter as tk
################################
#使用pillow读取显示图片
from PIL import Image,ImageTk
################################
window_width,window_height=500,300
root=tk.Tk()
image=Image.open('背景.jpg').resize((window_width,window_height))
backgroud_image=ImageTk.PhotoImage(image)
root.title('测试')
root.geometry(f'{window_width}x{window_height}')
main_canvas=tk.Canvas(root,width=window_width,height=window_height)
main_canvas.create_image(0,0,anchor='nw',image=backgroud_image)
main_canvas.pack(fill='both',expand=True)
root.mainloop()

效果: 

这是按照上述思路运行代码后的效果,接下来我们使用pyinstaller试着将其打包成一个exe文件

打包方法可以见这篇文章:https://blog.csdn.net/weixin_73953650/article/details/146621947?fromshare=blogdetail&sharetype=blogdetail&sharerId=146621947&sharerefer=PC&sharesource=weixin_73953650&sharefrom=from_linkhttps://blog.csdn.net/weixin_73953650/article/details/146621947?fromshare=blogdetail&sharetype=blogdetail&sharerId=146621947&sharerefer=PC&sharesource=weixin_73953650&sharefrom=from_link

 打包后,我们运行该exe文件,报错:

报错原因很简单,就是无法找到背景.jpg这个文件,这是因为pyinstaller只能用来打包py文件

解决思路

        解决上述问题的办法很多,但是个人认为最简单的一种便是把图片转换成py文件即可,到这儿有小伙伴可能会问怎么把图片写入到py文件中呢?

        嘿嘿,这里我们其实只需要使用base64将图片encode成字符串,便可以实现上述操作,在用的时候将其从存储这个base64字符串的py文件中导入,然后再decode一下成bytes便可正常使用了……

图像转换为base64字符串

import base64
image=open('背景.jpg','rb')
base64_string=base64.b64encode(image.read())
image.close()
print(base64_string)

使用上述几行代码便可以实现将图片转换为base64_string

结果:

将base64字符串写入py文件 

写入文件很简单,只需在上述代码中使用open语句完成即可

import base64
image=open('背景.jpg','rb')
base64_string=base64.b64encode(image.read())
image.close()
with open('BackGround.py','w') as py:
    py.write(f'img={base64_string}')

结果:

说明:

  1. 千万不要手贱,随便增删上述结果中的任何一个字符,否则无法转回成图像!
  2. 在写入的字符串前加了一个img=是为了将其作为py文件中的变量,方便我们使用import调用

从py文件导入base64字符串并转换为图片

import base64
from BackGround import img
from io import BytesIO
from PIL import Image
image=Image.open(BytesIO(base64.b64decode(img)))

运行上述代码后,此时的image便又被转换为原始图像了

结果:

        然后,按照最开始正常显示的思路,我们将这个image实例经过ImageTK后再传入给tkinter的控件就可以了。

图片转换base64字符串完整代码 

import os
import base64
def convert_image_to_string(image_path:str,py_path):
    '''
    运行该代码后将在当前目录下生成一
    Args:
        image_path:图片路径,倘若你的图片与当前py文件同一个文件夹下用名称也可以\n
        py_path:输出的python文件路径,可以只是名称比如BackGround.py或者直接传入一个地址\n
    '''
    #image_path是文件名的时候,路径为当前工作区文件夹+图像名字,否则是图像原始路径,os.path会自动处理这一问题,不需要我们手动判断
    image_path=os.path.join(os.curdir,image_path)
    #py_path是文件名的时候,路径为当前工作区文件夹+py名字,否则是py文件原始路径,os.path会自动处理这一问题,不需要我们手动判断
    py_path=os.path.join(os.curdir,py_path)
    print(py_path)
    with open(py_path,'w') as py:
        image=open(image_path,'rb')
        py.write(f'ImageString={base64.b64encode(image.read())}')
        image.close()
convert_image_to_string(image_path='背景.jpg',py_path='bg.py')

        运行上述代码后,给定image_path路径下的图片将会经过base64编码后在给定的py_path路径下生成一个py文件,py文件的内容是ImageString= 'base64字符串'

结果:

当前工作区文件夹下多了一个bg.py文件,内容是:

base64字符串转换图片完整代码

前边我们已经生成了一个名为bg.py的文件,那么接下来我们只需从bg.py中导入ImageString这个字符串变量,然后将其bas64.bsdecode后经过Bytesio将

import base64
from bg import ImageString#刚刚转换过的base64字符串变量
from io import BytesIO
from PIL import Image,ImageTk
def convert_string_to_image(ImageString:str,size:tuple):
    '''
    Args:
        ImageString:图像的base64字符串变量
        size:图像尺寸,(width,height)
    '''
    image_bytes=base64.b64decode(ImageString)#decode方法返回的是bytes型数据
    #pillow的Image下的open方法需要是文件路径或IObytes类型数据
    #因此需要使用BytesIO将bytes图像数据转换为io_bytes类型
    io_image_bytes=BytesIO(image_bytes)
    image=Image.open(io_image_bytes).resize(size)
    return image
image=convert_string_to_image(ImageString,size=(500,300))
image

 结果:

当然,如果这个图像你是打算用于tkinter控件作为背景,那么还需在函数返回值的前一行添加一个

image=ImageTk.PhotoImage(image)

这样我们就可以愉快地使用了!

测试

我们按照这样的方法来试一下,看看这样将图片作为背景的GUI是否能够在打包后正常显示

GUI完整代码:

import base64
import tkinter as tk
from bg import ImageString#刚刚转换过的base64字符串变量
from io import BytesIO
from PIL import Image,ImageTk
def convert_string_to_image(ImageString:str,size:tuple):
    '''
    Args:
        ImageString:图像的base64字符串变量
        size:图像尺寸,(width,height)
    '''
    image_bytes=base64.b64decode(ImageString)#decode方法返回的是bytes型数据
    #pillow的Image下的open方法需要是文件路径或IObytes类型数据
    #因此需要使用BytesIO将bytes图像数据转换为io_bytes类型
    io_image_bytes=BytesIO(image_bytes)
    image=Image.open(io_image_bytes).resize(size)
    image=ImageTk.PhotoImage(image)
    return image
################################
window_width,window_height=500,300
root=tk.Tk()
root.title('测试')
root.geometry(f'{window_width}x{window_height}')
main_canvas=tk.Canvas(root,width=window_width,height=window_height)
backgroud_image=convert_string_to_image(ImageString,size=(window_width,window_height))
main_canvas.create_image(0,0,anchor='nw',image=backgroud_image)
main_canvas.pack(fill='both',expand=True)
root.mainloop()

 结果:

双击运行打包好后的exe文件,没有出现前边所示的错误,正常运行!

总结

        以上便是解决pyinstallerGUI打包时无法打包图片问题的所有内容,如果对你有用,免费的赞和收藏来一波支持作者😁😁

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2325164.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝桥杯真题------R格式(高精度乘法,高精度加法)

对于高精度乘法和加法的同学可以学学这几个题 高精度乘法 高精度加法 文章目录 题意分析部分解全解 后言 题意 给出一个整数和一个浮点数,求2的整数次幂和这个浮点数相乘的结果最后四舍五入。、 分析 我们可以发现,n的范围是1000,2的1000次方非常大&am…

Nginx — Nginx安装证书模块(配置HTTPS和TCPS)

一、安装和编译证书模块 [rootmaster nginx]# wget https://nginx.org/download/nginx-1.25.3.tar.gz [rootmaster nginx]# tar -zxvf nginx-1.25.3.tar.gz [rootmaster nginx]# cd nginx-1.25.3 [rootmaster nginx]# ./configure --prefix/usr/local/nginx --with-http_stub_…

回调后门基础

回调后门概述 回调后门(Reverse Shell)是一种常见的攻击方式,攻击者通过受害主机主动连接到远程服务器(攻击者控制的机器),从而获得远程控制权限。 工作原理 受害者主机 运行一个恶意代码,尝…

深度学习 Deep Learning 第13章 线性因子模型

深度学习 Deep Learning 第13章 线性因子模型 内容概要 本章深入探讨了线性因子模型,这是一类基于潜在变量的概率模型,用于描述数据的生成过程。这些模型通过简单的线性解码器和噪声项捕捉数据的复杂结构,广泛应用于信号分离、特征提取和数…

【个人笔记】用户注册登录思路及实现 springboot+mybatis+redis

基本思路 获取验证码接口 验证码操作用了com.pig4cloud.plugin的captcha-core这个库。 AccountControl的"/checkCode"接口代码,通过ArithmeticCaptcha生成一张验证码图片,通过text()函数得到验证码的答案保存到变量code,然后把图…

聚类(Clustering)基础知识3

文章目录 一、聚类的性能评价1、聚类性能评价(1)聚类性能评价方法: 2、参考模型 (reference model)(1)数据集:(2)聚类结果:(3)参考模型&#xff1…

RK3588使用笔记:设置程序/服务开机自启

一、前言 一般将系统用作嵌入式设备时肯定要布置某些程序,这时候就需要对程序设置开机自己,否则每次都要人为启动,当有些嵌入式系统未连接显示屏或者无桌面环境去操作启动程序时,程序自启就是必须的了,本文介绍在纯li…

python实现股票数据可视化

最近在做一个涉及到股票数据清洗及预测的项目,项目中需要用到可视化股票数据这一功能,这里我与大家分享一下股票数据可视化的一些基本方法。 股票数据获取 目前,我已知的使用python来获取股票数据方式有以下三种: 爬虫获取,实现…

JavaScript DOM与元素操作

目录 DOM 树、DOM 对象、元素操作 一、DOM 树与 DOM 对象 二、获取 DOM 元素 1. 基础方法 2. 现代方法(ES6) 三、修改元素内容 四、修改元素常见属性 1. 标准属性 2. 通用方法 五、通过 style 修改样式 六、通过类名修改样式 1. className 属…

ARM向量表

向量表作用说明RVBAR在 AArch64 中,重置向量不再是异常向量表的一部分。 有复位向量的专用配置输入引脚和寄存器。在 AArch64 中,处理器从 IMPLEMENTAION‑DEFINED 地址开始执行, 该地址由硬件输入引 脚RVBARADDR定义, 可以通过 R…

leetcode刷题日记——除自身以外数组的乘积

[ 题目描述 ]: [ 思路 ]: 题目要求获取数组中每个元素除自己以外的各元素的乘积最简单的方法就是算出数组所有元素的乘积,然后除以自身,即可得到除自身外各元素的乘积 但要考虑到其自身为0的情况,即当期自身为0时&am…

【信奥一本通提高篇】基础算法之贪心算法

原文 https://bbs.fmcraft.top/blog/index.php/archives/22/ 贪心算法 概述 近年来的信息学竞赛试题,经常出现求一个问题的可行解或最优解的题目。这类问题就是我们通常所说的最优化问题。贪心算法是求解这类问题的一种常用算法。在众多的算法中,贪心…

PyQt6实例_批量下载pdf工具_批量pdf网址获取

目录 前置: 步骤: step one 安装包 step two 获取股票代码 step three 敲代码,实现 step four 网址转pdf网址 视频 前置: 1 本系列将以 “PyQt6实例_批量下载pdf工具”开头,放在 【PyQt6实例】 专栏 2 本节讲…

KMeans算法案例

KMeans算法案例 案例介绍 已知:客户性别、年龄、年收入、消费指数 需求:对客户进行分析,找到业务突破口,寻找黄金客户 数据集共包含顾客的数据, 数据共有 4 个特征, 数据共有 200 条。接下来,使用聚类算法对具有相似…

IDApro直接 debug STM32 MCU

使用IDA pro 逆向分析muc 固件的时候, 难免要进行一些动态的debug,来进一步搞清楚一些内存的数据、算法等,这时候使用远程debug 的方式直接在mcu上进行debug 最合适不过了。 不过有个前提条件就是一般来说有的mcu 会被运行中的代码屏蔽 RDP、…

六十天前端强化训练之第三十六天之E2E测试(Cypress)大师级完整指南

欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗,谢谢大佬! 目录 一、知识讲解 1. E2E测试核心概念 2. Cypress框架特性 3. 工作原理 4. 测试金字塔定位 二、核心代码示例:用户登录全流程测试 三、实现效果展示 四、学习要…

20250330-傅里叶级数专题之离散傅里叶变换(5/6)

5. 傅里叶级数专题之离散傅里叶变换 推荐视频: 工科生以最快的速度理解离散傅立叶变换(DFT) 哔哩哔哩 20250328-傅里叶级数专题之数学基础(0/6)-CSDN博客20250330-傅里叶级数专题之傅里叶级数(1/6)-CSDN博客20250330-傅里叶级数专题之傅里叶变换(2/6)-CSDN博客20250330-傅里叶…

3.29:数据结构-绪论线性表-上

一、时间复杂度 1、ADT 2、定义法计算时间复杂度:统计核心语句的总执行次数 (1)例题1,与2022年的真题对比着写 此题关键在于求和公式的转化,类型为:线性循环嵌套非线性循环 2022年那道题如果考场上实在脑…

大模型架构记录13【hr agent】

一 Function calling 函数调用 from dotenv import load_dotenv, find_dotenvload_dotenv(find_dotenv())from openai import OpenAI import jsonclient OpenAI()# Example dummy function hard coded to return the same weather # In production, this could be your back…

conda 清除 tarballs 减少磁盘占用 、 conda rename 重命名环境、conda create -n qwen --clone 当前环境

🥇 版权: 本文由【墨理学AI】原创首发、各位读者大大、敬请查阅、感谢三连 🎉 声明: 作为全网 AI 领域 干货最多的博主之一,❤️ 不负光阴不负卿 ❤️ 文章目录 conda clean --tarballsconda rename 重命名环境conda create -n qwen --clone …