大家好,才哥又来了!
又要上班了,春节总是过的太匆匆。
最近接到一个需求,把一批照片按照分辨率进行分类存储,再将其中指定宽高比的照片设置为特定的分辨率且添加水印。
以下是简单的效果:
目录:
文章目录
1. 直接上代码1.1. 原图资源1.2. 实现逻辑1.3. 水印效果1.4. 完整代码2.PIL模块功能简介2.1. 加载图片并获取其属性2.2. 创建图片2.3. 裁剪图片2.4. 调整图片大小2.5. 旋转图片2.6. 在图片上绘制文本2.7. 复制和粘贴图片附:标准颜色的名称和值1. 直接上代码
本次案例的原图来源于此前图虫网爬取的美女照片,大家可以参考《Python爬虫 | 批量爬取某图网站高质量小姐姐照片 》最后的代码自行获取。
原图共902张,分辨率大概有178种,这里需要遍历全部的照片然后进行分组,再对分辨率为1200*800的照片进行尺寸调整为 600*400,并添加水印可以叫我才哥
字样。
1.1. 原图资源
1.2. 实现逻辑
自己绘制一个logo,底色透明循环遍历文件夹下的全部.jpg和.png图片文件获取图片文件的分辨率按照分辨率创建子文件夹,如果存在则无需创建判断分辨率比例是否为1200/800,如果是则进行重设分辨率为600*400,并在右下角粘贴logo将图片文件存储在对应分辨率子文件夹模块化以下三部分:
绘制文字logo粘贴logo到照片遍历全部照片,按照分辨率分类
1.3. 水印效果
1.4. 完整代码
我们将绘制文件logo和复制粘贴logo到照片功能独立定义成函数,然后再进行处理。
# -*- coding: utf-8 -*-"""Created on Wed Feb 17 20:30:56 @author: 可以叫我才哥(公众号同名)"""from PIL import Image, ImageDraw, ImageFontimport os# 绘制文字logodef drawLogo(logoName):# 创建宽*高为200*100的空白图片对象,未指定背景色则为透明的黑色logo = Image.new('RGBA',(200,100))# 创建一个ImageDraw对象draw = ImageDraw.Draw(logo)# 设置字体为 FZZJ-YGYTKJW.TTF,字号为 32Font = ImageFont.truetype('FZZJ-YGYTKJW.TTF', 32)# 在左顶点坐标为(0,50)的位置绘制颜色为橙色orange的‘可以叫我才哥’文本draw.text((0,50),logoName, fill='orange', font=Font)# 将logo图片旋转45度logo = logo.rotate(45,expand=True)return logo# 复制粘贴logo到照片def pasteLogo(im,logo):# 获取logo的宽和高logoWidth, logoHeight = logo.size# 获取照片的宽和高Width, Height = im.size# 将logo图片粘贴到指定照片的指定位置(指定照片的右下角)im.paste(logo, (Width-logoWidth, Height-logoHeight), logo)return im# 对全部照片按照分辨率进行分类,特殊照片加上logodef fenleiPic(yuantuFolder, fenleiFolder, logo):# 遍历文件夹for foldername, subfolders, filenames in os.walk(yuantuFolder):n = 0# 遍历文件for filename in filenames:# 判断文件后缀(即只处理jpg和png图片文件),不是则跳出进入下一个循环if filename.endswith('.jpg') or filename.endswith('.png'):# 读取图片文件im = Image.open(os.path.join(yuantuFolder,filename))# 获取图片文件尺寸(宽*高)w,h = im.size# print(w,h)# 创建 宽-高 文件夹folder = os.path.join(fenleiFolder, str(w)+'-'+str(h))# 判断文件夹是否存在,存在则进行下一步程序,不存在则新建一个if os.path.exists(folder):passelse:os.makedirs(folder) # 判断 宽*高 比,如果是就先进行resize后再存储if w/h == 1200/800:pic = im.resize((600,400))# 调用添加logo函数pic = pasteLogo(pic,logo)pic.save(os.path.join(folder,filename))# print(f'\r{n}张图片已经处理',end='')else:# 存储图片到对应文件夹(名为 宽-高 的文件夹)im.save(os.path.join(folder,filename))n = n+1print(f'\r{n}张图片已经处理',end='')else:continue# 主函数def main():# 切换到指定目录os.chdir(r'F:\PythonCool\Python基础库')# 获取当前目录path = os.getcwd()# 设置原图所在文件夹yuantuFolder = os.path.join(path,'图片')# 设置整理的的图片所在文件夹fenleiFolder = os.path.join(path,'PIL')logo = drawLogo('可以叫我才哥')fenleiPic(yuantuFolder, fenleiFolder, logo)if __name__ == "__main__":main()
2.PIL模块功能简介
其实,在完整代码中,我们基本对每行代码都有进行注释,这里主要是对代码中涉及到的模块相关属性及函数方法进行一一介绍,方便大家举一反三!
安装PIL库:
PIL库是第三方库,我们需要手动安装以下哈!
pip install pillow
2.1. 加载图片并获取其属性
from PIL import Image# 加载图片pic = Image.open('牛.jpg')pic
In [1]: # 分辨率...: pic.sizeOut[1]: (413, 275)In [2]: # 图片名称...: pic.filenameOut[2]: '牛.jpg'In [3]: # 图片格式...: pic.formatOut[3]: 'JPEG'In [4]: # 图片格式详细描述...: pic.format_descriptionOut[4]: 'JPEG (ISO 10918)'In [5]: # 存储图片...: pic.save('牛.png')
2.2. 创建图片
创建图片用Image.new()
方法。
Image.new()
的参数如下:
字符串’RGBA’,将颜色模式设置为 RGBA(还有其他模式,但本书没有涉及);大小,是两个整数元组,作为新图片的宽度和高度;图片开始采用的背景颜色,是一个表示 RGBA 值的四整数元组,默认为透明的黑色。你可以用ImageColor.getcolor()
函数的返回值作为这个参数。另外,Image.new()也支持传入标准颜色名称的字符串。
关于 标准颜色名称的字符串,可以参考文末的附。
In [6]: im = Image.new('RGBA',(80,60), 'purple')In [7]: imOut[7]:
In [8]: im2 = Image.new('RGBA',(20,20)) # 默认背景色为透明的黑色In [9]: im2
2.3. 裁剪图片
裁剪图像是指在图像内选择一个矩形区域,并删除矩形之外的一切。 Image 对象的crop()
方法接受一个矩形元组,返回一个 Image 对象,表示裁剪后的图像。
矩形元组(这里就是要裁剪的区域)包括左列和顶行的像素,直至但不包括右列和底行的像素。
In [10]: pic.crop((100,100,200,200))Out[10]:
2.4. 调整图片大小
resize()
方法在 Image 对象上调用,返回指定宽度和高度的一个新 Image 对象。它接受两个整数的元组作为参数,表示返回图像的新高度和宽度。
In [11]: pic.sizeOut[11]: (413, 275)In [12]: pic.resize((300, 180))Out[12]:
2.5. 旋转图片
图片可以用rotate()
方法旋转,该方法返回旋转后的新 Image 对象,并保持原始Image 对象不变。 rotate()的参数是一个整数或浮点数,表示图片逆时针旋转的度数。
In [13]: pic.rotate(45) # 直接旋转时,图片尺寸不变Out[13]:
In [14]: pic.rotate(45,expand=True) # expand参数设置为True时,会扩展图片大小Out[14]:
2.6. 在图片上绘制文本
如果需要在图像上画线、矩形、圆形、其他简单形状或文本,就用 Pillow 的ImageDraw
模块。
这里只介绍绘制 文本:
ImageDraw 对象还有text()
方法,用于在图像上绘制文本。 text()方法有 4 个参数:xy、 text、 fill 和 font
。
xy 参数是两个整数的元组,指定文本区域的左上角;text 参数是想写入的文本字符串;可选参数 fill 是文本的颜色;可选参数 font 是一个ImageFont
对象,用于设置文本的字体和大小。
In [15]: from PIL import Image, ImageDraw, ImageFont...: # 创建宽*高为200*100的空白图片对象,未指定背景色则为透明的黑色...: logo = Image.new('RGBA',(200,100))...: # 创建一个ImageDraw对象...: draw = ImageDraw.Draw(logo)...: # 设置字体为 FZZJ-YGYTKJW.TTF,字号为 32...: Font = ImageFont.truetype('FZZJ-YGYTKJW.TTF', 32)...: # 在左顶点坐标为(0,50)的位置绘制颜色为橙色orange的‘可以叫我才哥’文本...: draw.text((0,50),'可以叫我才哥', fill='orange', font=Font)In [26]: logoOut[26]:
2.7. 复制和粘贴图片
copy()
方法返回一个新的 Image 对象,它和原来的 Image 对象具有一样的图像。如果需要修改图像,同时也希望保持原有的版本不变,这非常有用。
In [17]: pic2 = pic.copy()In [18]: pic2Out[18]:
paste()
方法在 Image 对象调用,将另一个图像粘贴在它上面,paste()方法有两个参数:一个“源” Image 对象,一个包含 x 和 y 坐标的元组,指明源 Image 对象粘贴到主 Image 对象时左上角的位置。
In [19]: pic2.paste(im) # 默认情况下,从左上角粘贴In [20]: pic2Out[20]:
In [21]: pic2.paste(logo,(200,0),logo) # 第三个参数情况下,“源”图片对象的透明背景也会带上In [22]: pic2Out[22]:
附:标准颜色的名称和值
如果觉得《Python基础模块:图像处理模块@PIL(批量分类处理图片及添加水印)》对你有帮助,请点赞、收藏,并留下你的观点哦!