查看原文
其他

Python基础模块:图像处理模块@PIL(批量分类处理图片及添加水印)

才哥 可以叫我才哥 2021-10-08




大家好,才哥又来了!

又要上班了,春节总是过的太匆匆。

最近接到一个需求,把一批照片按照分辨率进行分类存储,再将其中指定宽高比的照片设置为特定的分辨率且添加水印。

以下是简单的效果:


目录:

  • 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. 实现逻辑

  1. 自己绘制一个logo,底色透明
  2. 循环遍历文件夹下的全部.jpg和.png图片文件
  3. 获取图片文件的分辨率
  4. 按照分辨率创建子文件夹,如果存在则无需创建
  5. 判断分辨率比例是否为1200/800,如果是则进行重设分辨率为600*400,并在右下角粘贴logo
  6. 将图片文件存储在对应分辨率子文件夹

模块化以下三部分:

  • 绘制文字logo
  • 粘贴logo到照片
  • 遍历全部照片,按照分辨率分类

1.3. 水印效果

可以叫我才哥水印

1.4. 完整代码

我们将绘制文件logo和复制粘贴logo到照片功能独立定义成函数,然后再进行处理。

# -*- coding: utf-8 -*-
"""
Created on Wed Feb 17 20:30:56 2021

@author: 可以叫我才哥(公众号同名)
"""


from PIL import Image, ImageDraw, ImageFont
import os

# 绘制文字logo
def drawLogo(logoName):
    # 创建宽*高为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),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

# 对全部照片按照分辨率进行分类,特殊照片加上logo
def 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):
                    pass
                else:
                    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+1
                print(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
牛.jpg
In [1]: # 分辨率
   ...: pic.size
Out[1]: (413275)

In [2]: # 图片名称
   ...: pic.filename
Out[2]: '牛.jpg'

In [3]: # 图片格式
   ...: pic.format
Out[3]: 'JPEG'

In [4]: # 图片格式详细描述
   ...: pic.format_description
Out[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]: im
Out[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.size
Out[11]: (413275)

In [12]: pic.resize((300180))
Out[12]: 
调整后的图片

2.5. 旋转图片

图片可以用 rotate()方法旋转,该方法返回旋转后的新 Image 对象,并保持原始Image 对象不变。rotate()的参数是一个整数或浮点数,表示图片逆时针旋转的度数。

In [13]: pic.rotate(45# 直接旋转时,图片尺寸不变
Out[13]: 
旋转45度
In [14]: pic.rotate(45,expand=True# expand参数设置为True时,会扩展图片大小
Out[14]: 
expand=True

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]: logo
Out[26]: 
可以叫我才哥

2.7. 复制和粘贴图片

copy()方法返回一个新的 Image 对象,它和原来的 Image 对象具有一样的图像。如果需要修改图像,同时也希望保持原有的版本不变,这非常有用。

In [17]: pic2 = pic.copy()

In [18]: pic2
Out[18]: 
复制的图片

paste()方法在 Image 对象调用,将另一个图像粘贴在它上面,paste()方法有两个参数:一个“源”  Image 对象,一个包含 x 和 y 坐标的元组,指明源 Image 对象粘贴到主 Image 对象时左上角的位置。

In [19]: pic2.paste(im) # 默认情况下,从左上角粘贴

In [20]: pic2
Out[20]: 
默认粘贴
In [21]: pic2.paste(logo,(200,0),logo) # 第三个参数情况下,“源”图片对象的透明背景也会带上

In [22]: pic2
Out[22]: 
带上源透明背景

附:标准颜色的名称和值

颜色名称字符串中文名称16进制RGB10进制RGB
aliceblue艾利斯兰#f0f8ff240,248,255
antiquewhite古董白#faebd7250,235,215
aqua浅绿色#00ffff0,255,255
aquamarine碧绿色#7fffd4127,255,212
azure天蓝色#f0ffff240,255,255
beige米色#f5f5dc245,245,220
bisque桔黄色#ffe4c4255,228,196
black黑色#0000000,0,0
blanchedalmond白杏色#ffebcd255,235,205
blue蓝色#0000ff0,0,255
blueviolet紫罗兰色#8a2be2138,43,226
brown褐色#a52a2a165,42,42
burlywood实木色#deb887222,184,135
cadetblue军兰色#5f9ea095,158,160
chartreuse黄绿色#7fff00127,255,0
chocolate巧可力色#d2691e210,105,30
coral珊瑚色#ff7f50255,127,80
cornflowerblue菊兰色#6495ed100,149,237
cornsilk米绸色#fff8dc255,248,220
crimson暗深红色#dc143c220,20,60
cyan青色#00ffff0,255,255
darkblue暗蓝色#00008b0,0,139
darkcyan暗青色#008b8b0,139,139
darkgoldenrod暗金黄色#b8860b184,134,11
darkgray暗灰色#a9a9a9169,169,169
darkgreen暗绿色#0064000,100,0
darkgrey暗灰色#a9a9a9169,169,169
darkkhaki暗黄褐色#bdb76b189,183,107
darkmagenta暗洋红#8b008b139,0,139
darkolivegreen暗橄榄绿#556b2f85,107,47
darkorange暗桔黄色#ff8c00255,140,0
darkorchid暗紫色#9932cc153,50,204
darkred暗红色#8b0000139,0,0
darksalmon暗肉色#e9967a233,150,122
darkseagreen暗海兰色#8fbc8f143,188,143
darkslateblue暗灰蓝色#483d8b72,61,139
darkslategray暗瓦灰色#2f4f4f47,79,79
darkslategrey暗瓦灰色#2f4f4f47,79,79
darkturquoise暗宝石绿#00ced10,206,209
darkviolet暗紫罗兰色#9400d3148,0,211
deeppink深粉红色#ff1493255,20,147
deepskyblue深天蓝色#00bfff0,191,255
dimgray暗灰色#696969105,105,105
dimgrey暗灰色#696969105,105,105
dodgerblue闪兰色#1e90ff30,144,255
firebrick火砖色#b22222178,34,34
floralwhite花白色#fffaf0255,250,240
forestgreen森林绿#228b2234,139,34
fuchsia紫红色#ff00ff255,0,255
gainsboro淡灰色#dcdcdc220,220,220
ghostwhite幽灵白#f8f8ff248,248,255
gold金色#ffd700255,215,0
goldenrod金麒麟色#daa520218,165,32
gray灰色#808080128,128,128
green绿色#0080000,128,0
greenyellow黄绿色#adff2f173,255,47
grey灰色#808080128,128,128
honeydew蜜色#f0fff0240,255,240
hotpink热粉红色#ff69b4255,105,180
indianred印第安红#cd5c5c205,92,92
indigo靛青色#4b008275,0,130
ivory象牙色#fffff0255,255,240
khaki黄褐色#f0e68c240,230,140
lavender淡紫色#e6e6fa230,230,250
lavenderblush淡紫红#fff0f5255,240,245
lawngreen草绿色#7cfc00124,252,0
lemonchiffon柠檬绸色#fffacd255,250,205
lightblue亮蓝色#add8e6173,216,230
lightcoral亮珊瑚色#f08080240,128,128
lightcyan亮青色#e0ffff224,255,255
lightgoldenrodyellow亮金黄色#fafad2250,250,210
lightgray亮灰色#d3d3d3211,211,211
lightgreen亮绿色#90ee90144,238,144
lightgrey亮灰色#d3d3d3211,211,211
lightpink亮粉红色#ffb6c1255,182,193
lightsalmon亮肉色#ffa07a255,160,122
lightseagreen亮海蓝色#20b2aa32,178,170
lightskyblue亮天蓝色#87cefa135,206,250
lightslategray亮蓝灰#778899119,136,153
lightslategrey亮蓝灰#778899119,136,153
lightsteelblue亮钢兰色#b0c4de176,196,222
lightyellow亮黄色#ffffe0255,255,224
lime酸橙色#00ff000,255,0
limegreen橙绿色#32cd3250,205,50
linen亚麻色#faf0e6250,240,230
magenta红紫色#ff00ff255,0,255
maroon粟色#800000128,0,0
mediumaquamarine中绿色#66cdaa102,205,170
mediumblue中兰色#0000cd0,0,205
mediumorchid中粉紫色#ba55d3186,85,211
mediumpurple中紫色#9370db147,112,219
mediumseagreen中海蓝#3cb37160,179,113
mediumslateblue中暗蓝色#7b68ee123,104,238
mediumspringgreen中春绿色#00fa9a0,250,154
mediumturquoise中绿宝石#48d1cc72,209,204
mediumvioletred中紫罗兰色#c71585199,21,133
midnightblue中灰兰色#19197025,25,112
mintcream薄荷色#f5fffa245,255,250
mistyrose浅玫瑰色#ffe4e1255,228,225
moccasin鹿皮色#ffe4b5255,228,181
navajowhite纳瓦白#ffdead255,222,173
navy海军色#0000800,0,128
oldlace老花色#fdf5e6253,245,230
olive橄榄色#808000128,128,0
olivedrab深绿褐色#6b8e23107,142,35
orange橙色#ffa500255,165,0
orangered红橙色#ff4500255,69,0
orchid淡紫色#da70d6218,112,214
palegoldenrod苍麒麟色#eee8aa238,232,170
palegreen苍绿色#98fb98152,251,152
paleturquoise苍宝石绿#afeeee175,238,238
palevioletred苍紫罗兰色#db7093219,112,147
papayawhip番木色#ffefd5255,239,213
peachpuff桃色#ffdab9255,218,185
peru秘鲁色#cd853f205,133,63
pink粉红色#ffc0cb255,192,203
plum洋李色#dda0dd221,160,221
powderblue粉蓝色#b0e0e6176,224,230
purple紫色#800080128,0,128
red红色#ff0000255,0,0
rosybrown褐玫瑰红#bc8f8f188,143,143
royalblue皇家蓝#4169e165,105,225
saddlebrown重褐色#8b4513139,69,19
salmon鲜肉色#fa8072250,128,114
sandybrown沙褐色#f4a460244,164,96
seagreen海绿色#2e8b5746,139,87
seashell海贝色#fff5ee255,245,238
sienna赭色#a0522d160,82,45
silver银色#c0c0c0192,192,192
skyblue天蓝色#87ceeb135,206,235
slateblue石蓝色#6a5acd106,90,205
slategray灰石色#708090112,128,144
slategrey灰石色#708090112,128,144
snow雪白色#fffafa255,250,250
springgreen春绿色#00ff7f0,255,127
steelblue钢兰色#4682b470,130,180
tan茶色#d2b48c210,180,140
teal水鸭色#0080800,128,128
thistle蓟色#d8bfd8216,191,216
tomato西红柿色#ff6347255,99,71
turquoise青绿色#40e0d064,224,208
violet紫罗兰色#ee82ee238,130,238
wheat浅黄色#f5deb3245,222,179
white白色#ffffff255,255,255
whitesmoke烟白色#f5f5f5245,245,245
yellow黄色#ffff00255,255,0
- 往期推荐 -① Python基础模块:日期与时间模块@time+datetime
② Python小玩意 | 操作excel来作画
③ 对着爬虫网页HTML学习Python正则表达式re


- END -


: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存