Search code examples
pythonflet

How to update an image frame displayed in Flet


I'm working with some recognition prompt which runs beside my actual program, these recog prompt cut and resize an image, constantly saving/deleting the image, changing it by the most actual recog frame.

Now, my problem is how to implement it with Flet, I've actually tried some common ways, which use ft.Image() and page.update(), container update and even controls update. But the image stays the same even if I erase it from my computer and the other image has the same name and format in the folder.

Here's an example of what I've tried.

import time
import flet as ft

def main(page: ft.Page):

    i = ft.Image(src='Python\\plate_0.jpg', on_animation_end= page.update())

    def animate(e):
        sw.content = ft.Image(
            src=f'Python\\plate_0.jpg{time.time()}'
        )
        page.update()

    sw = ft.AnimatedSwitcher(
        i,
        transition=ft.AnimatedSwitcherTransition.SCALE,
        duration=500,
        reverse_duration=500,
        switch_in_curve=ft.AnimationCurve.BOUNCE_OUT,
        switch_out_curve=ft.AnimationCurve.BOUNCE_IN,
    )

    page.add(
        sw,
        ft.ElevatedButton("Animate!", on_click=animate),
    )

ft.app(target=main)

This code displays the image, but when it is replaced on the OS, even if you click on "Animate" nothing happens beside the screen going blank. I've made other tests, creating a class (ImageSwitcher), using OpenCV to read the image and even abusing the page.update() on every possible way.


Solution

  • Yeah, I found the solution, and it's quite simple if you think properly. If the file name stays the same, but the older image is gone, then you'll need to declare a "new-same" file path, so the code will search the file again.

    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"Python\\plate_0.jpg" # First Reachable Path
    pil_photo = image.open(image_path) # Pillow Opens the Image
    arr = np.asarray(pil_photo) # Numpy transforms it into an array
    
    pil_img = image.fromarray(arr) # Then you convert it in an image again
    buff = BytesIO() # Buffer
    pil_img.save(buff, format="JPEG") # Save it
    
    def main(page= ft.Page):
        image_string = base64.b64encode(buff.getvalue()).decode('utf-8')
        image1 = Image(src_base64=image_string)
        page.window_width = 375
        page.window_height = 300
    
        def updateTest(value):
            image_path = r"Python\\plate_0.jpg" # Read the path again
    
            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")
            image1.src_base64 = newstring
    
            image1.update() # "Voí'la"
    
        page.add(
            ft.Row(controls=[
                image1
            ], alignment='center'),
            ft.Row(controls=[
                ft.TextButton("Test", on_click=updateTest)
            ], alignment='center')
        )
    
    ft.app(target=main)