0

My tkinter user-interface involves two large Canvas widgets that are used to display photographs. The photographs update periodically, since they are being fed from live cameras. Problem: with some probability, the Canvas flashes white as it switches photographs. This makes for a very irritating display. I cannot include my whole program, as it is complex and includes external hardware, but here is the core update code. Please, can someone suggest an improvement to it to get rid of the flashing?

from PIL import Image,ImageTk

def previewUpdate(bytes, cameraID):
    # Update whichever view just got a new image
    view = canvasPicker[cameraID]
        # gets a View object, subclass of Canvas, below
    image = bytesToImage(bytes)
    view.display(image)


class View(tk.Canvas):
    def __init__(self, parent, width=1000, height=750, index=-1):
        super().__init__(parent, width=width, height=height)
        self.width = width
        self.height = height
        . . .

    def display(self, image):
        self.scale = min(self.width / image.width, self.height / image.height)
        image1 = image.resize((int(image.width * self.scale), int(image.height * self.scale)))
        self.photoImage = ImageTk.PhotoImage(image=image1)
        try:
            self.itemconfig(self.imageObject, image=self.photoImage)
        except Exception as e:
            print("display failure:  ", e)
Joymaker
  • 813
  • 1
  • 9
  • 23
  • 4
    This probably boils down to execution time. The image loading is slow enough to be visible. One fix I can think of is not removing the old image until after the new one is loaded in. Would at least remove the white blink. – Lone Lunatic Nov 29 '22 at 14:45
  • still if u would have included a minimum reproducible code, we could help you. – Mustafa KÜÇÜKDEMİRCİ Nov 29 '22 at 14:55

1 Answers1

0

Thank you, Lone Lunatic, for highlighting the problem. This line:

self.photoImage = ImageTk.PhotoImage(image=image1)

with some probability allows the prior PhotoImage to be garbage collected before the following line displays the new one, and that leaves a white interval. Quite simple… if you have your head around the weird inner workings of tkinter and PhotoImages. Here is the corrected, working code:

def display(self, image):
    self.scale = min(self.width / image.width, self.height / image.height)
    image1 = image.resize((int(image.width * self.scale), int(image.height * self.scale)))
    image2 = ImageTk.PhotoImage(image=image1)
    try:
        self.itemconfig(self.imageObject, image=image2)
        self.photoImage = image2
    except Exception as e:
        print("display failure:  ", e)
Joymaker
  • 813
  • 1
  • 9
  • 23