我在 Python 中有一个概念证明,它只是不断重绘窗口,跟踪时间,并随着时间的推移删除图像。这看起来不错,但感觉很笨拙,不确定如果有 1000 个图像我是否相信它能运行。下面分享了示例。
无论如何,有没有更好的方法用另一种语言来做到这一点?如果是这样,有人有例子吗?
import pygame
import win32api
import win32con
import win32gui
import time
import random
class testHug():
def __init__(self):
pygame.init()
self.screen_width = 800
self.screen_height = 600
self.screen = pygame.display.set_mode((self.screen_width, self.screen_height))
self.hwnd = pygame.display.get_wm_info()["window"]
win32gui.SetWindowLong(self.hwnd, win32con.GWL_EXSTYLE, win32gui.GetWindowLong(
self.hwnd, win32con.GWL_EXSTYLE) | win32con.WS_EX_LAYERED)
win32gui.SetLayeredWindowAttributes(self.hwnd, win32api.RGB(255, 0, 128), 0, win32con.LWA_COLORKEY)
self.screen.fill((255, 0, 128))
pygame.display.flip()
self.image_list = [
pygame.image.load("image.png"),
pygame.image.load("image2.png"),
pygame.image.load("image3.png")
]
self.duration = 4000
self.killtime = 10000
self.current_ticker_time = pygame.time.get_ticks()
self.image_dict = {'user1' : {'image': pygame.image.load("image.png"), 'shown':0, 'starttime': self.current_ticker_time, 'widthmodifier': random.randrange(-350,350), 'heightmodifier': random.randrange(-250,250)} }
self.current_ticker_time = pygame.time.get_ticks()
self.image_dict['user2'] = {'image': pygame.image.load("image2.png"), 'shown':0, 'starttime': self.current_ticker_time, 'widthmodifier': random.randrange(-350,350), 'heightmodifier': random.randrange(-250,250)}
self.current_ticker_time = pygame.time.get_ticks()
self.image_dict['user3'] = {'image': pygame.image.load("image3.png"), 'shown':0, 'starttime': self.current_ticker_time, 'widthmodifier': random.randrange(-350,350), 'heightmodifier': random.randrange(-250,250)}
self.current_ticker_time = pygame.time.get_ticks()
self.image_dict['user4'] = {'image': pygame.image.load("image4.png"), 'shown':0, 'starttime': self.current_ticker_time, 'widthmodifier': random.randrange(-350,350), 'heightmodifier': random.randrange(-250,250)}
self.running = True
def processImages(self, user, image):
self.current_ticker_time = pygame.time.get_ticks()
self.image_dict[user] = {'image': pygame.image.load(image), 'shown':0, 'starttime': self.current_ticker_time, 'widthmodifier': random.randrange(-350,350), 'heightmodifier': random.randrange(-250,250)}
self.image_index = 0
while self.running:
elapsed_time = pygame.time.get_ticks() - self.current_ticker_time
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
if elapsed_time >= self.killtime and self.image_index >= len(self.image_dict):
break
if elapsed_time >= self.duration and self.image_index < len(self.image_dict):
self.image_index += 1
self.screen.fill((255, 0, 128))
pygame.display.flip()
for x in range(0, self.image_index):
if (self.image_index <= len(self.image_dict)):
imageToGrab = "user"+ str(x+1)
if self.image_dict[imageToGrab]["shown"] == 0:
self.image_dict[imageToGrab]["starttime"] = pygame.time.get_ticks()
self.image_dict[imageToGrab]["shown"] = 1
imageElapsedTime = pygame.time.get_ticks() - int(self.image_dict[imageToGrab]["starttime"])
print("starttime, imageElapsedTime, and imageToGrab", self.image_dict[imageToGrab]["starttime"], imageElapsedTime, imageToGrab)
if imageElapsedTime < (self.duration * 2.5):
image_rect = self.image_dict[imageToGrab]["image"].get_rect()
image_rect.center = ((self.screen_width / 2)+self.image_dict[imageToGrab]["widthmodifier"], (self.screen_height / 2)+self.image_dict[imageToGrab]["heightmodifier"])
self.screen.blit(self.image_dict[imageToGrab]["image"], image_rect)
pygame.display.flip() #redraw screen
self.current_ticker_time = pygame.time.get_ticks()
pygame.quit()
if __name__ == '__main__':
th = testHug()
th.processImages('user5', "image5.png")
如果我正确理解您的目标,则以编程方式将图像加载到
self.image_list
可能会更容易,而不是逐行显式加载它们。您甚至可以将所有图像存储在一个位置,例如 images
文件,然后使用 os.listdir()
逐张读取每个图像。它可能看起来像这样(考虑这是伪代码):
import ... # your imports here
from os import listdir, path # use this to read every file in a directory
class testHug():
def __init__(self):
... # your pygame window setup code here
# create this as an empty list instead
self.image_list = []
# set this to your images file path, directory, etc.
images_file_path = "\directory\to\your\images"
# gives you a list of filenames in the image folder
images_in_file = os.listdir(images_file_path)
# for each image file found in your folder
for _image in images_in_file:
# use path.join to connect the images folder directory
# to the individual image file's name
full_image_path = path.join(images_file_path, _image)
# load the image file
_loaded_image = pygame.image.load(full_image_path)
# add your newly loaded image to the image list
self.image_list.append(_loaded_image)
从那里开始,现在创建了
self.image_list
,您可以执行类似的循环来应用随机定时事件并将每个图像放入dict
中:
# like before, create the image_dict as an empty dict
self.image_dict = {}
# for every image loaded into the self.image_list
# we use an i-iterating loop instead of an access loop
for i in range(len(self.image_list)):
# set the current ticker time
self.current_ticker_time = pygame.time.get_ticks()
# create your dictionary entry's key ("user1", "user2", etc)
dict_key = "user" + str(i + 1)
# create your image dict key:value pair like you did originally
# however, difference is that you will use the already loaded image
# instead of loading it again...
new_pair = {dict_key :
{'image': self.image_list[i],
'shown': 0,
'starttime': self.current_ticker_time,
'widthmodifier': random.randrange(-350,350),
'heightmodifier': random.randrange(-250,250)
}
}
# add the new key:value pair to the dictionary
self.image_dict[dict_key] = new_pair
# self.image_dict now holds a dict key:val pair
# for every image you load in your images file
现在,您对图像数量的担忧是有道理的。将所有这些图像一次性加载到内存中对于硬件来说会非常昂贵。但是,这个程序的用例是什么?您认为您会实际上在 1,000 张图像上使用它吗?如果是这样,那么这肯定会使运行该程序的大部分机器崩溃......但是,这段代码可能能够在最多 100-200 个图像上运行(假设它们不是非常大的图像文件)。这对于您计划使用程序的方式来说满意吗?
如果您确实想将其用于大量图像,您可能希望将其更改为一次加载单个图像,创建滚动条,并在图像到达其显示时间结束后卸载 。这样,您可以在一个文件中包含 1000 亿张图像(我知道这很疯狂),但只能加载一个,几乎任何计算机都可以轻松处理。
我希望这对您有所帮助,并且我正确理解了您的目标。让我知道!