将图片插入sqlite3后在tkinter窗口展示报错无法识别图像文件怎么办
问题根因
报错的核心原因是存入SQLite blob 字段的数据格式错误:你直接将cv2.imread()返回的numpy数组作为blob存入数据库,该数组是OpenCV特有的像素矩阵对象,不是标准的图片文件二进制流,读取时PIL无法识别该数据格式,因此抛出无法识别图片文件的错误。
此外你原有代码中还存在一处图片显示的隐性bug:将ImageTk.PhotoImage对象转为numpy数组后赋值给Label的image属性,会导致tkinter丢失图片引用,选中图片后无法正常在标签页展示。
修复方案
1. 插入逻辑修改(推荐直接存原始图片字节)
无需额外用OpenCV读取,直接读取图片文件的原始二进制内容存入数据库即可,修改Insert函数内的对应代码:
# 原有展示图片的代码修改,去掉np.array转换,保留PhotoImage引用避免被回收 img = ImageTk.PhotoImage(Image.open(filename)) panel = Label(self.Tab_Control2) panel.config(image=img) panel.image = img # 额外保留引用,防止图片被GC回收显示空白 panel.pack(side="bottom", fill="both", expand="yes") ASK = messagebox.askquestion("HR", "Are you wanting to insert picture into your database ?", icon='warning') if ASK == 'yes': # 直接读取原始图片文件的二进制内容 with open(filename, 'rb') as f: img_byte = f.read() conn = sqlite3.connect('datastorage.db') c = conn.cursor() c.executescript('drop table if exists Structure1;') c.execute("create table if not exists Structure1 (img blob)") # 存入标准图片二进制流 c.execute("insert into Structure1 values (?)", (img_byte,)) conn.commit() conn.close() messagebox.showinfo("HR", "Done")
2. 需用OpenCV处理图片的存储方案
如果你需要先通过OpenCV对图片做裁剪、改色等处理再存储,需要将处理后的numpy数组编码为标准图片格式的字节流再存入:
# 读取并处理图片 img_cv = cv2.imread(filename) # 此处可添加你需要的OpenCV图片处理逻辑 # 将numpy数组编码为jpg格式的字节流 success, encoded_img = cv2.imencode('.jpg', img_cv) if success: img_byte = encoded_img.tobytes() # 后续将img_byte存入数据库即可,步骤和上面的方案一致
3. 展示逻辑验证
你原有Display函数的逻辑无需修改,插入正确的图片二进制流后即可正常读取展示。
内容的提问来源于stack exchange,提问作者Ahmed Mohammed Mohammed Morgan
相关产品推荐
相关产品推荐

