在 Flet 应用中动态更新图片,特别是当图片文件名不变但内容变化时,直接使用 page.update() 方法可能会失效。这是因为 Flet 可能会缓存图片,导致即使文件内容改变,显示的仍然是旧的图片。解决这个问题需要绕过缓存,强制 Flet 重新加载图片。
以下是一种实现动态刷新图片的方法:
- 读取图片文件: 使用 pillow (PIL) 库读取图片文件。
- 转换为 numpy 数组: 将图片转换为 NumPy 数组。
- 转换回图片对象: 将 NumPy 数组转换回 Pillow 的图片对象。
- 使用 BytesIO 创建内存缓冲区: 创建一个内存缓冲区,用于存储图片数据。
- 将图片保存到缓冲区: 将图片以 JPEG 格式保存到内存缓冲区。
- 编码为 Base64 字符串: 将内存缓冲区中的图片数据编码为 Base64 字符串。
- 更新 ft.Image 控件: 将 Base64 字符串赋值给 ft.Image 控件的 src_base64 属性。
- 调用 image1.update() 方法:调用image1.update()刷新图片控件。
import numpy as np import base64 import flet as ft from flet import Image from io import BytesIO from PIL import Image as image image_path = r"pythonplate_0.jpg" # 初始图片路径 def main(page=ft.Page): page.window_width = 375 page.window_height = 300 # 初始图片加载和编码 pil_photo = image.open(image_path) arr = np.asarray(pil_photo) pil_img = image.fromarray(arr) buff = BytesIO() pil_img.save(buff, format="JPEG") image_string = base64.b64encode(buff.getvalue()).decode('utf-8') image1 = Image(src_base64=image_string) def update_image(e): """更新图片的函数""" nonlocal image1 # 声明 image1 为非局部变量 # 重新读取图片 pil_photo = image.open(image_path) arr = np.asarray(pil_photo) pil_img = image.fromarray(arr) buff = BytesIO() pil_img.save(buff, format="JPEG") newstring = base64.b64encode(buff.getvalue()).decode("utf-8") # 更新 Image 控件的 src_base64 属性 image1.src_base64 = newstring image1.update() page.add( ft.Row(controls=[image1], alignment='center'), ft.Row(controls=[ft.TextButton("Test", on_click=update_image)], alignment='center') ) ft.app(target=main)
代码解释:
- image_path: 指定了图片文件的路径。 每次点击更新按钮的时候,都会重新读取该路径下的图片,因此确保该路径下的图片已经被更新。
- update_image(e) 函数:这个函数是关键,它负责重新读取图片,将其转换为 Base64 字符串,并更新 ft.Image 控件的 src_base64 属性。 每次点击按钮都会执行该函数。
- image1.update(): 调用 image1.update() 方法,强制 Flet 刷新 ft.Image 控件。
- nonlocal image1: image1 是在 main 函数中定义的,如果在 update_image 函数中要修改它,需要使用 nonlocal 关键字声明。
注意事项:
- 确保安装了 Pillow 库:pip install Pillow。
- 如果图片文件非常大,频繁的读取和编码可能会影响性能。可以考虑使用其他优化方法,例如使用线程或进程来异步处理图片。
- 如果图片格式不是 JPEG,需要修改 pil_img.save(buff, format=”JPEG”) 中的 format 参数。
总结:
通过重新读取图片文件并将其转换为 Base64 编码的字符串,可以有效地解决 Flet 中动态刷新图片的问题。这种方法可以确保每次都显示最新的图片内容,即使文件名保持不变。 这种方法适用于需要实时显示外部程序修改的图片的情况,例如监控画面或图像处理结果。
评论(已关闭)
评论已关闭