传递新图像时,使用自己的计时器将图像动态添加到窗口?

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

我在 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")

python image dynamic timer
1个回答
0
投票

如果我正确理解您的目标,则以编程方式将图像加载到

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 亿张图像(我知道这很疯狂),但只能加载一个,几乎任何计算机都可以轻松处理。

我希望这对您有所帮助,并且我正确理解了您的目标。让我知道!

© www.soinside.com 2019 - 2024. All rights reserved.