如何解决Python中PIL打开cp1251编码图片的Unicode解码错误?
解决UnicodeDecodeError:图片选择与显示的编码问题
问题原因
你代码里用filedialog.askopenfile()返回的是文本模式打开的文件对象,但图片是二进制格式文件,文本模式会尝试用系统默认编码(这里是cp1251)解析二进制数据,自然触发解码错误。
修复步骤
- 替换
askopenfile为askopenfilename,这个函数直接返回文件路径字符串,而非打开的文件对象 - 用获取到的路径字符串调用
Image.open() - 保留图片对象的引用(避免被Python垃圾回收机制回收,导致图片无法显示)
修正后的完整代码
from customtkinter import * from PIL import ImageTk, Image set_appearance_mode('System') set_default_color_theme('dark-blue') window = CTk() # Window window.geometry("800x520") # 全局变量保存图片引用,避免被回收 selected_image = None def select_image(): global selected_image # 改用askopenfilename获取文件路径 file_path = filedialog.askopenfilename(title="Select an image", filetypes=(('png files', '*.png'), ('jpg files', '*.jpg'), ('jpeg files', '*.jpeg'), ('bmp files', '*.bmp'), ('all image files', '*.png *.jpg *.jpeg *.bmp'))) if not file_path: # 处理用户取消选择的情况 return print(file_path) selected_image = ImageTk.PhotoImage(Image.open(file_path)) # 先创建label再布局,方便绑定图片引用 label = CTkLabel(window, image=selected_image) label.image = selected_image # 额外绑定引用,双重保险 label.place(x=0, y=0) image_button = CTkButton(window, text="I", bg_color='white', fg_color='white', hover_color='yellow', width=25, height=25, text_color='black', command=select_image) image_button.place(x=425, y=10) window.mainloop() # Loop
关键修改说明
- 替换文件选择函数:
askopenfilename直接返回路径,避免了文本模式打开二进制文件的编码问题 - 添加全局变量/引用绑定:
selected_image设为全局变量,同时绑定到label的image属性,确保图片对象不会被垃圾回收,保证显示正常 - 增加取消选择处理:当用户打开对话框后取消选择,不会触发后续报错
内容的提问来源于stack exchange,提问作者Little Developer
相关产品推荐
相关产品推荐

