如何在python中创建快速幻灯片?

问题描述 投票:0回答:2

我试图用python创建幻灯片,以循环5500张图像,速度比手动完成的快。我使用了tkinter,参数slide_interval应该可以完成这项工作。例如,如果将slide_interval = 5000设置为幻灯片,则幻灯片放映的时间确实会更长,但是如果将其设置为500,50或5,则幻灯片放映的时间就没有差异。感兴趣的时间是每张图片花费1或0.5秒。

这里是代码:

#!/usr/bin/env python3
"""Display a slideshow from a list of filenames"""

import os
import tkinter

from itertools import cycle
from PIL import Image, ImageTk


class Slideshow(tkinter.Tk):
    """Display a slideshow from a list of filenames"""
    def __init__(self, images, slide_interval):
        """Initialize

        images = a list of filename 
        slide_interval = milliseconds to display image
        """
        tkinter.Tk.__init__(self)
        self.geometry("+0+0")
        self.slide_interval = slide_interval
        self.images = None
        self.set_images(images)
        self.slide = tkinter.Label(self)
        self.slide.pack()

    def set_images(self, images):
         self.images = cycle(images)

    def center(self):
        """Center the slide window on the screen"""
        self.update_idletasks()
        w = self.winfo_screenwidth()
        h = self.winfo_screenheight()
        size = tuple(int(_) for _ in self.geometry().split('+')[0].split('x'))
        x = w / 2 - size[0] / 2
        y = h / 2 - size[1] / 2
        self.geometry("+%d+%d" % (x, y))

    def set_image(self):
        """Setup image to be displayed"""
        self.image_name = next(self.images)
        filename, ext = os.path.splitext(self.image_name)
        self.image = ImageTk.PhotoImage(Image.open(self.image_name))

    def main(self):
        """Display the images"""
        self.set_image()
        self.slide.config(image=self.image)
        self.title(self.image_name)
        self.center()
        self.after(self.slide_interval, self.start)

    def start(self):
        """Start method"""
        self.main()
        self.mainloop()


if __name__ == "__main__":
    slide_interval = 1


    import glob
    images = glob.glob("traralgon/*.jpg")

    # start the slideshow
    slideshow = Slideshow(images, slide_interval)
    slideshow.start()
python tkinter slideshow
2个回答
0
投票

问题是您在每个时间间隔都调用self.main()self.mainloop()。这将导致巨大的性能问题,并且可能在一两秒钟后崩溃。您永远不应多次调用mainloop(),并且在每个循环上重新创建整个UI也没有意义。

相反,您需要编写一个获取图像的函数,然后配置现有标签,而不是在每次迭代时重新创建整个GUI。

示例:

def main(self):
    ...
    self.next_image()

def next_image(self):
    self.image_name = next(self.images)
    filename, ext = os.path.splitext(self.image_name)
    self.image = tkinter.PhotoImage(file=self.image_name)
    self.slide.configure(image=self.image)
    self.after(self.slide_interval, self.next_image)

0
投票

可能是这样:

import tkinter as tk


class Application(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        self.title("Slideshow")
        self.geometry("256x256")
        self.resizable(width=False, height=False)
        self.current_slide = tk.Label(self)
        self.current_slide.pack()
        self.duration_ms = 1000

    def set_image_directory(self, path):
        from pathlib import Path
        from PIL import Image, ImageTk
        from itertools import cycle

        image_paths = Path(path).glob("*.jpg")
        self.images = cycle(zip(map(lambda p: p.name, image_paths), map(ImageTk.PhotoImage, map(Image.open, image_paths))))

    def display_next_slide(self):
        name, self.next_image = next(self.images)
        self.current_slide.config(image=self.next_image)
        self.title(name)
        self.after(self.duration_ms, self.display_next_slide)

    def start(self):
        self.display_next_slide()

def main():

    application = Application()
    application.set_image_directory("dir/to/images")
    application.start()
    application.mainloop()


if __name__ == "__main__":
    import sys
    sys.exit(main())
© www.soinside.com 2019 - 2024. All rights reserved.