由于项目需要100w张图片,在网上下载的图片数据往往是很大尺寸的,此时无论是对照片的存储,转移等操作往往需要消耗大量时间,为了更好的对图片操作,于是对图片进行尺寸缩小,由原先的100多G变换到十多G,从而很好的对图片进行上传存储等操作。刚开始时候处理图片没用用到进程,处理起来很慢,于是在网上查找有关python进程的方法,经过研究使用Python 多进程 multiprocessing.Pool类。
这里将对multiprocessing.Pool类进行简要介绍:
Pool类
在使用python进行系统管理时,特别是同时操作多个文件目录或者远程控制多台主机,并行操作可以节约大量的时间。Pool类可以提供指定数量的进程供用户调用,当有新的请求提交到Pool中时,如果池还没有满,就会创建一个新的进程来执行请求。如果池满,请求就会告知先等待,直到池中有进程结束,才会创建新的进程来执行这些请求。
下面对multiprocessing.Pool类中的几个方法进行介绍:
- map(func, iterable[, chunksize=None])
Pool类中的map方法,与内置的map函数用法行为基本一致,它会使进程阻塞直到返回结果。注意,虽然第二个参数是一个迭代器,但在实际使用中,必须在整个队列都就绪后,程序才会运行子进程。
- close()
关闭进程池(pool),使其不在接受新任务。
- terminate()
结束工作进程,不在处理未处理的任务。
- join()
主进程阻塞等待子进程的退出,join方法必须在close或terminate之后使用。
这里是我对100w图片做尺寸处理时的代码:
import os
import time
from PIL import Image
from multiprocessing import Pool
def get_file_path(path):
img_paths = []
dirs = os.listdir(path)
for file_dir in dirs:
file_path = os.path.join(path, file_dir)
img_names = os.listdir(file_path)
for img_name in img_names:
img_path = os.path.join(file_path, img_name)
img_paths.append(img_path)
return img_paths
def resize_image(file_name):
try:
img = Image.open(file_name)
new_img = img.resize((250, 250), Image.ANTIALIAS)
new_img.save(file_name)
except:
print(file_name)
if __name__ == '__main__':
start = time.time()
path = r'C:\Users\Alvin_Fang\Downloads\identities_0'
img_paths = get_file_path(path)
pool = Pool(6)
pool.map(resize_image, img_paths)
pool.close()
pool.join()
end = time.time()
print(end - start)
注意:在Windows上要想使用进程模块,就必须把有关进程的代码写在当前.py文件的if __name__ == ‘__main__’ :语句的下面,才能正常使用Windows下的进程模块,Unix/Linux下则不需要。