Pyglet图像查看器项目如何在不减慢程序速度的情况下在后台缓存图像?

2024-10-03 02:44:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我想做的是为自己制作一个图像查看器程序。我开始尝试pygame和Tkinter,但得出的结论是我最好的选择是使用pyglet。 我要实现的是一个快速的JPEG浏览器,只具有基本功能。最重要的功能是快速显示图像。我的结论是需要某种图像缓存来实现这一点。将图像作为精灵载入pyglet对于提高速度非常有效,但我需要动态地这样做。一些图像应该保存在内存中,以便快速显示。 而“旧”图像应该被清除,以防止RAM和GPU内存被填满。所有这些都不会干扰程序的执行和已在RAM和/或GPU中的图像的显示。在


我选择pyglet是因为它有比PyGame更好的事件循环系统。不会消耗这么多CPU。我使用的是python2.7和repository中最新的Pyglet,因为它支持64位python。到目前为止我所拥有的:

import pyglet
from pyglet.window import key

import sys
import glob
import os

def generateFileList(folder):
    searchstring = folder + "\*.jpg"
    flist = list()
    for match in glob.iglob(searchstring):
        if os.path.isfile(match):
            flist.append(match)
    return flist

class HelloWorldWindow(pyglet.window.Window):
    def __init__(self):
        super(HelloWorldWindow, self).__init__(fullscreen=True)

        if len(sys.argv) > 1:
            files = list(sys.argv[1:]) #exclude this scripts name
        else:
            print('Not enough arguments... terminating program.')
            raise SystemExit(0)

        folder = os.path.split(files[0])[0]
        self.flist = generateFileList(folder)
        self.loader = pyglet.resource.Loader(folder)
        self.index = 0
        self.ipreloadA = 1
        self.ipreloadB = 0
        self.sprite = False
        self.createSprite(0)

    def next(self):
        if (len(self.flist) - 1) > self.index:
            self.index += 1
        self.setpreload()
        self.createSprite(1)
    def previews(self):
        if self.index > 0:
            self.index -= 1
        self.setpreload()
        self.createSprite(-1)
    def setpreload(self):
        if self.index == 0:
            self.ipreloadA = 0
            self.ipreloadB = 1
        elif self.index == (len(self.flist) - 1):
            self.ipreloadA = self.index - 1
            self.ipreloadB = self.index
        else:
            self.ipreloadA = self.index - 1
            self.ipreloadB = self.index + 1

    def createSprite(self, direction):
        if direction == 0:
            self.image = pyglet.image.load(self.flist[self.index])
        elif direction == -1:
            self.image = self.imageA
        elif direction == 1:
            self.image = self.imageB
        if self.sprite:
            self.sprite.delete()
        self.sprite = pyglet.sprite.Sprite(self.image)
        self.preload()
    def preload(self):
        if not self.ipreloadA == self.index:
            fName = os.path.basename(self.flist[self.ipreloadA])
            self.imageA = self.loader.image(fName)
        else:
            self.imageA = self.image
        if not self.ipreloadB == self.index:
            fName = os.path.basename(self.flist[self.ipreloadB])
            self.imageB = self.loader.image(fName)
        else:
            self.imageB = self.image

    def on_draw(self):
        self.clear()
        if self.sprite:
            self.sprite.draw()

    def on_key_press(self, symbol, modifiers):
        if symbol == key.ESCAPE:
            pyglet.app.exit()
        elif symbol == key.LEFT:
            self.previews()
        elif symbol == key.RIGHT:
            self.next()

if __name__ == '__main__':
    window = HelloWorldWindow()
    pyglet.app.run()

我试图用上面的代码实现的是,图像首先被加载,然后在显示之前创建一个精灵。上面代码的问题是它仍然会变慢。似乎在等待从硬盘加载图像。在

下面是一个没有失败的atempt的更基本的版本:

^{pr2}$

另外请注意,为了简单起见,这里没有调整图像大小。在


Tags: key图像imageimportselfindexifos