上一章节,我们用wxPython给图片格式转换器写了一个简单的GUI,测试时用的是几百张小图片,我们再来测试一下批量处理照片,照片的文件比较大,每张都有好几M。
果真出问题了,界面卡死了。目标文件夹有新的图片还在不断生成,说明程序仍在运行,但是界面已经卡死。在处理复杂的任务的时候,不能把任务写在UI线程里,需要单独使用线程处理。代码修改如下:
# 点击转换格式按钮,触发此方法,获取图片输入输出路径和图片输出类型,转换图片。def ConvertButtonEvent(self, event): srcPath = self.srcPathTextCtrl.GetValue() # 原图片路径 dstPath = self.dstPathTextCtrl.GetValue() # 目标图片路径 if srcPath == '': wx.MessageBox('请选择图片输入路径', '消息', wx.OK | wx.ICON_INFORMATION) return if dstPath == '': wx.MessageBox('请选择图片输出路径', '消息', wx.OK | wx.ICON_INFORMATION) return ext = self.extCombobox.GetValue() # 目标图片类型 # 用新线程执行处理图片的任务,并使用元组做为参数传入原图片路径、目标图片路径、目标图片类型 _thread.start_new_thread(self.process_image, (srcPath, dstPath, ext,)) # 处理图片def process_image(self, srcPath, dstPath, ext): file_list = file_walk(srcPath) for srcImagePath in file_list: print(srcImagePath) if os.path.getsize(srcImagePath) == 0: continue try: image = Image.open(srcImagePath) image = ImageOps.exif_transpose(image) srcImageName = os.path.split(srcImagePath)[1] dstImageName = os.path.splitext(srcImageName)[0] + ext dstImagePath = os.path.join(dstPath, dstImageName) image.save(dstImagePath) self.tip.SetLabel('正在转换:%s' % srcImagePath) except Exception as e: print(e)self.tip.SetLabel('转换完成')
好了,界面不会卡死了,问题解决。
但是感觉这个转换速度是真让人捉急!有什么好的办法让它能加快速度呢?对了,既然用了线程,为什么不用多线程来处理呢?继续修改代码
# 用新线程执行处理图片的任务,并使用元组做为参数传入原图片路径、目标图片路径、目标图片类型 # _thread.start_new_thread(self.process_image, (srcPath, dstPath, ext,)) thread_pool = ThreadPoolExecutor(4) file_list = file_walk(srcPath) for srcImagePath in file_list: # print(srcImagePath) if os.path.getsize(srcImagePath) == 0: continue thread_pool.submit(self.process_image, srcImagePath, dstPath, ext)# 处理图片def process_image(self, srcImagePath, dstPath, ext): print(srcImagePath) try: image = Image.open(srcImagePath) image = ImageOps.exif_transpose(image) srcImageName = os.path.split(srcImagePath)[1] dstImageName = os.path.splitext(srcImageName)[0] + ext dstImagePath = os.path.join(dstPath, dstImageName) image.save(dstImagePath) self.tip.SetLabel('正在转换:%s' % srcImagePath)except Exception as e:print(e)
这里用到了线程池
thread_pool = ThreadPoolExecutor(4)
其中4代表线程池创建了4个线程,也就是说可以同时处理4张图片。那么是不是创建线程越多越好呢?其实并不是的,经过测试我发现处理线程数跟CPU的核心数有关,当创建的线程数越过CPU核心数时,速度也不会提升了。据说Python的多线程实际上并不能真正利用多核,所以如果使用多线程实际上还是在一个核上做并发处理。不过,如果使用多进程就可以真正利用多核,因为各进程之间是相互独立的,不共享资源,可以在不同的核上执行不同的进程,达到并行的效果。
我们这里把线程数设置为CPU的核心数。到设备管理器和任务管理器里查看一下CPU的核心数
import osprint(os.cpu_count())
修改一下代码
thread_pool = ThreadPoolExecutor(max_workers=os.cpu_count())
现在是不是快多了!
留言与评论(共有 0 条评论) “” |