【问题标题】:Delays in threads when compositing multiple sets of images using imagemagick with python使用带有 python 的 imagemagick 合成多组图像时的线程延迟
【发布时间】:2019-09-04 04:11:08
【问题描述】:

我正在树莓派中构建一个应用程序,用户单击一个按钮,该应用程序在倒计时后拍摄 3 张照片,并将这 3 张照片放入照片模板中。第一次点击按预期工作,但如果我第二次点击它,它会倒计时,但直到几秒钟后才会拍照,而且我点击按钮越多,这种延迟就会越长。问题是当应用程序将 3 张照片合成到模板中时,这需要一些时间来处理,并且会延迟用于捕获照片的线程。这是因为 ImageService.pycreatePhotoboothImage 函数中的 bash 命令无法异步执行,还是我的线程有问题?任何帮助或建议都会很棒!

GUIApp.py

class GUIApp:
    def __init__(self):
        self.root = tk.Tk()
        self.root.attributes('-zoomed', True)
        self.buttonCountDown = tk.Button(text='Count Down', command=self.capturePhotos)
        self.buttonCountDown.pack()
        self.label = tk.Label(text='Ready!', bg='#3D434F', fg='white', font=('Helvetica', 100, 'bold'))
        self.label.pack(side='top', fill='both', expand=True)
        self.queue = queue.Queue()
        self.captureQueue = queue.Queue()
        self.imageProcessQueue = queue.Queue()
        self.imageService = imageService.ImageService()
        self.cameraService = cameraService.CameraService()
        self.imageCount = 0
        self.images = []
        threading.Thread(target=self.listenToCaptureQueue).start()                
        threading.Thread(target=self.listenToQueue).start()
        threading.Thread(target=self.listenToImageProcessQueue).start()
        self.root.mainloop()

    def countDown(self, seconds):
        for i in range(seconds, 0, -1):
            self.queue.put(i)
            time.sleep(1)
        self.queue.put('SMILE!')
        time.sleep(1)
        self.captureQueue.put(True)        

    def listenToQueue(self):
        while True:
            try:
                if self.queue.empty() == False:
                    s = self.queue.get(0)
                    self.label['text'] = s
                elif self.queue.empty() == True: 
                    pass
            except queue.Empty:
                pass

    def listenToCaptureQueue(self):
        while True:
            try:
                if self.captureQueue.empty() == False:
                    if self.captureQueue.get(0):
                        ## Take a photo               
                        self.label['text'] = 'Please wait...'
                        filePath = self.cameraService.captureImage()
                        self.images.append("%r"%filePath)
                        self.imageCount += 1
                        if self.imageCount < 3:
                            # Start timer again to take photo
                            threading.Thread(target=self.countDown, args=(3,)).start()
                        else:
                            self.buttonCountDown['state'] = 'normal'  
                            self.label['text'] = 'Ready!'
                            self.imageProcessQueue.put(self.images)
                elif self.captureQueue.empty() == True:
                    pass
            except queue.Empty:
                pass

    def listenToImageProcessQueue(self):
        while True:
            try:
                if self.imageProcessQueue.empty() == False:  
                        # Composite the 3 photos to the template                 
                        images = self.imageProcessQueue.get(0)     
                        templatePath = '/home/pi/Documents/Test/template.jpg'
                        destinationPath = '/home/pi/Documents/Test/compositeImage.jpg'
                        self.imageService.createPhotoboothImage(images, templatePath, destinationPath)
                elif self.imageProcessQueue.empty() == True:
                    pass
            except queue.Empty:
                pass           

    def capturePhotos(self):
        self.images = []
        self.imageCount = 0
        self.buttonCountDown['state'] = 'disabled'         
        threading.Thread(target=self.countDown, args=(5,)).start()

ImageService.py

class ImageService:      
    def createPhotoboothImage(self, images, templatePath, destinationPath):
        cmd = 'convert ' + templatePath + ' \( ' + images[0] + ' -scale "18.5%" \) -geometry +53+401 -composite \( ' + images[1] + ' -scale "9.02%" \) -geometry +1205.5+401 -composite \( ' + images[2] + ' -scale "9.02%" \) -geometry +1205.5+790 -composite ' + destinationPath
        subprocess.call(cmd, shell=True)

【问题讨论】:

    标签: python imagemagick imagemagick-convert


    【解决方案1】:

    由于全局解释器锁,线程不会在 Python 中并行运行,如果您真的想要并行执行,请使用进程。例如,参见multiprocessing 模块。

    【讨论】:

    • 有道理!将在一天结束时尝试这个。
    猜你喜欢
    • 1970-01-01
    • 2013-08-16
    • 2016-02-28
    • 2017-04-01
    • 2021-04-18
    • 1970-01-01
    • 2017-07-12
    • 2020-03-27
    • 1970-01-01
    相关资源
    最近更新 更多