由于项目需要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下则不需要。