我想做的是为自己制作一个图像查看器程序。我开始尝试pygame和Tkinter但得出结论,我最好的选择是使用pyglet。 我想要实现的是一个具有基本功能的快速JPEG查看器。最重要的功能是快速显示图像。我总结了实现这一点需要某种图像缓存。将图像加载到pyglet中,因为Sprites非常适合速度,但我需要动态地执行此操作。应将一些图像保存在内存中,以便快速显示。 虽然应该清除“旧”图像,以防止RAM和GPU内存填满。所有这些都不会干扰程序的执行和显示已经在RAM和/或GPU中的图像。
我之所以选择pyglet是因为它有比PyGame更好的事件循环系统。不消耗那么多CPU。我正在使用python 2.7和最新的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()
我尝试使用上面的代码实现的是首先加载图像然后在显示之前创建一个精灵。上述代码的问题在于它仍然会变慢。似乎等待从HDD加载图像。
这是一个更基本的版本,没有我失败的尝试:
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
def createSprite(imagePath):
pass
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.index = 0
self.sprite = False
self.createSprite()
def next(self):
if (len(self.flist) - 1) > self.index:
self.index += 1
self.createSprite()
def previews(self):
if self.index > 0:
self.index -= 1
self.createSprite()
def createSprite(self):
self.image = pyglet.image.load(self.flist[self.index])
if self.sprite:
self.sprite.delete()
self.sprite = pyglet.sprite.Sprite(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()
另请注意,为简单起见,此处没有调整图像大小。