使用Python PIL库读取文件批量处理图片大小实现
作者:BEARZPY
python 批量处理图片大小
写博客,文档的时候常常要附上很多图片,但是图片的尺寸往往不符合我们的要求,手动一个一个修改尺寸再保存,太浪费时间了,既然学了 Python,当然就要物尽其用。本文实现了批量修改同级目录下的 image\src 文件夹下的所有图片,并输出到 image\output 文件夹下,可以设定具体像素,也可以只设定水平像素或者垂直像素, 另一边按原图比例进行缩放。使用 Python 处理图片大小需要使用 PIL 库,PIL:Python Imaging Library,是一个图片处理库,需要自行安装。
PIL 读取图片大小
下面是修改单张图片尺寸的函数。
from PIL import Image set_img_type = "" def resize_image(filein, fileout, set_horizontal_length, set_vertical_length): if set_vertical_length == 0 and set_horizontal_length == 0: return img = Image.open(filein) img_size = img.size img_horizontal_length = img_size[0] img_vertical_length = img_size[1] if set_vertical_length == 0: set_vertical_length = set_horizontal_length * img_vertical_length / img_horizontal_length if set_horizontal_length == 0: set_horizontal_length = set_vertical_length * img_horizontal_length / img_vertical_length print img_horizontal_length, img_vertical_length print set_horizontal_length, set_vertical_length # resize image with high-quality out = img.resize((set_horizontal_length, set_vertical_length), Image.ANTIALIAS) if set_img_type == "": out.save(fileout) else: out.save(fileout, set_img_type)
代码简介
- filein 图片输入文件名(带路径)。
- fileout 图片输出文件名(带路径)。
- set_horizontal_length 希望修改成的水平长度,如果为 0,自动使用原图比例和设定的竖直长度计算该值。
- set_vertical_length 希望修改成的竖直长度,如果为 0,自动使用原图比例和设定的水平长度计算该值。
- img.size 包含了两个值,比如(1080, 1920),第一个值是宽度(水平长度),第二值是高度(竖直长度)。
- set_img_type 如果为空,保持原图片类型,如果非空则保存成对应图片类型,比如
set_img_type = "png"
,会把图片以 png 数据格式进行保存。
PIL 批量处理图片
上面已经介绍了处理单张图片的方法,想要处理文件夹下的所有图片就要能遍历文件夹里所有的文件。这里使用递归遍历出所有的文件,再分别进行处理。
使用递归遍历文件夹
def check_image(root_dir): if not os.path.isdir(root_dir): return for lists in os.listdir(root_dir): path = os.path.join(root_dir, lists) if os.path.isfile(path): # TODO: resize image. if os.path.isdir(path): check_image(path)
代码简介:
判断当前文件夹中的每个元素,如果是文件夹则进入该文件夹递归调用,并重复读取判断操作。如果是文件,则在代码中的 TODO 标签处进行相应处理。注:这里默认 image\src 文件夹下不会出现非图片文件。
准备输出工作
目标是把修改后的图片输出到 image\output 文件夹下,这里需要做三件事,在 output 目录下创建对应 src 目录下的子文件夹,生成图片保存的文件名(带路径),修改生成图片的后缀名。将递归代码修改如下,增加了 find_last_point 函数用于找到后缀名前的小数点来修改后缀名。
import os import os.path def check_image(root_dir): if not os.path.isdir(root_dir): return for lists in os.listdir(root_dir): path = os.path.join(root_dir, lists) # handle output path of dir and file out_path = image_output_dir + path[9:] print path if os.path.isfile(path): # handle output file name point_position = find_last_point(out_path) if not set_img_type == "": out_path = out_path[0:point_position + 1] + set_img_type print out_path # resize image. resize_image(path, out_path, horizontal_length, vertical_length) if os.path.isdir(path): # make dir in image\output if not os.path.exists(out_path): os.mkdir(out_path) print out_path check_image(path) def find_last_point(file_path): position = 0 temp = 0 while temp != -1: temp = file_path.find(".") if temp != -1: position = temp file_path = file_path[ temp + 1:] return position
清理 output 文件夹
如果只生成不清理,output 文件夹会越来越臃肿,想要找到转换的图片还需要花额外的时间,所以这里选择程序刚开始就删除整个 output 文件夹,并新建一个空的 output 文件夹。
import os import os.path import shutil def clear(): if os.path.exists(image_output_dir): shutil.rmtree(image_output_dir) if not os.path.exists(image_output_dir): os.mkdir(image_output_dir)
完整代码
PIL 不支持修改为 jpg 后缀,所以如果设置生成 jpg 文件,程序会自动修改成 jpeg 文件。
import os import os.path import shutil from PIL import Image horizontal_length = 260 vertical_length = 0 image_src_dir = r"image\src" image_output_dir = r"image\output" set_img_type = "" # set_img_type = "bmp" # set_img_type = "jpeg" # set_img_type = "png" def test_run(): if os.path.exists(image_output_dir): shutil.rmtree(image_output_dir) if not os.path.exists(image_output_dir): os.mkdir(image_output_dir) global set_img_type if set_img_type == "jpg": set_img_type = "jpeg" check_image(image_src_dir) print "finish." def resize_image(filein, fileout, set_horizontal_length, set_vertical_length): if set_vertical_length == 0 and set_horizontal_length == 0: return img = Image.open(filein) img_size = img.size img_horizontal_length = img_size[0] img_vertical_length = img_size[1] if set_vertical_length == 0: set_vertical_length = set_horizontal_length * img_vertical_length / img_horizontal_length if set_horizontal_length == 0: set_horizontal_length = set_vertical_length * img_horizontal_length / img_vertical_length print img_horizontal_length, img_vertical_length print set_horizontal_length, set_vertical_length # resize image with high-quality out = img.resize((set_horizontal_length, set_vertical_length), Image.ANTIALIAS) if set_img_type == "": out.save(fileout) else: out.save(fileout, set_img_type) def check_image(root_dir): if not os.path.isdir(root_dir): return for lists in os.listdir(root_dir): path = os.path.join(root_dir, lists) # handle output path of dir and file out_path = image_output_dir + path[9:] print path if os.path.isfile(path): # handle output file name point_position = find_last_point(out_path) if not set_img_type == "": out_path = out_path[0:point_position + 1] + set_img_type print out_path # resize image. resize_image(path, out_path, horizontal_length, vertical_length) if os.path.isdir(path): # make dir in image\output if not os.path.exists(out_path): os.mkdir(out_path) print out_path check_image(path) def find_last_point(file_path): position = 0 temp = 0 i = 0 while temp != -1: temp = file_path.find(".") if temp != -1: if i == 0: position = position + temp else: position = position + temp + 1 file_path = file_path[temp+1:] i = 1 return position if __name__ == "__main__": test_run()
以上就是使用Python PIL库读取文件批量处理图片大小实现的详细内容,更多关于Python PIL处理图片大小的资料请关注脚本之家其它相关文章!