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



腾讯课堂 | Python网络爬虫与文本分析~~

大家好,才哥又来了!

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

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

以下是简单的效果:

目录:

  • 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]: (413, 275)

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]: (413, 275)

In [12]: pic.resize((300, 180))
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进制RGB 10进制RGB
aliceblue 艾利斯兰 #f0f8ff 240,248,255
antiquewhite 古董白 #faebd7 250,235,215
aqua 浅绿色 #00ffff 0,255,255
aquamarine 碧绿色 #7fffd4 127,255,212
azure 天蓝色 #f0ffff 240,255,255
beige 米色 #f5f5dc 245,245,220
bisque 桔黄色 #ffe4c4 255,228,196
black 黑色 #000000 0,0,0
blanchedalmond 白杏色 #ffebcd 255,235,205
blue 蓝色 #0000ff 0,0,255
blueviolet 紫罗兰色 #8a2be2 138,43,226
brown 褐色 #a52a2a 165,42,42
burlywood 实木色 #deb887 222,184,135
cadetblue 军兰色 #5f9ea0 95,158,160
chartreuse 黄绿色 #7fff00 127,255,0
chocolate 巧可力色 #d2691e 210,105,30
coral 珊瑚色 #ff7f50 255,127,80
cornflowerblue 菊兰色 #6495ed 100,149,237
cornsilk 米绸色 #fff8dc 255,248,220
crimson 暗深红色 #dc143c 220,20,60
cyan 青色 #00ffff 0,255,255
darkblue 暗蓝色 #00008b 0,0,139
darkcyan 暗青色 #008b8b 0,139,139
darkgoldenrod 暗金黄色 #b8860b 184,134,11
darkgray 暗灰色 #a9a9a9 169,169,169
darkgreen 暗绿色 #006400 0,100,0
darkgrey 暗灰色 #a9a9a9 169,169,169
darkkhaki 暗黄褐色 #bdb76b 189,183,107
darkmagenta 暗洋红 #8b008b 139,0,139
darkolivegreen 暗橄榄绿 #556b2f 85,107,47
darkorange 暗桔黄色 #ff8c00 255,140,0
darkorchid 暗紫色 #9932cc 153,50,204
darkred 暗红色 #8b0000 139,0,0
darksalmon 暗肉色 #e9967a 233,150,122
darkseagreen 暗海兰色 #8fbc8f 143,188,143
darkslateblue 暗灰蓝色 #483d8b 72,61,139
darkslategray 暗瓦灰色 #2f4f4f 47,79,79
darkslategrey 暗瓦灰色 #2f4f4f 47,79,79
darkturquoise 暗宝石绿 #00ced1 0,206,209
darkviolet 暗紫罗兰色 #9400d3 148,0,211
deeppink 深粉红色 #ff1493 255,20,147
deepskyblue 深天蓝色 #00bfff 0,191,255
dimgray 暗灰色 #696969 105,105,105
dimgrey 暗灰色 #696969 105,105,105
dodgerblue 闪兰色 #1e90ff 30,144,255
firebrick 火砖色 #b22222 178,34,34
floralwhite 花白色 #fffaf0 255,250,240
forestgreen 森林绿 #228b22 34,139,34
fuchsia 紫红色 #ff00ff 255,0,255
gainsboro 淡灰色 #dcdcdc 220,220,220
ghostwhite 幽灵白 #f8f8ff 248,248,255
gold 金色 #ffd700 255,215,0
goldenrod 金麒麟色 #daa520 218,165,32
gray 灰色 #808080 128,128,128
green 绿色 #008000 0,128,0
greenyellow 黄绿色 #adff2f 173,255,47
grey 灰色 #808080 128,128,128
honeydew 蜜色 #f0fff0 240,255,240
hotpink 热粉红色 #ff69b4 255,105,180
indianred 印第安红 #cd5c5c 205,92,92
indigo 靛青色 #4b0082 75,0,130
ivory 象牙色 #fffff0 255,255,240
khaki 黄褐色 #f0e68c 240,230,140
lavender 淡紫色 #e6e6fa 230,230,250
lavenderblush 淡紫红 #fff0f5 255,240,245
lawngreen 草绿色 #7cfc00 124,252,0
lemonchiffon 柠檬绸色 #fffacd 255,250,205
lightblue 亮蓝色 #add8e6 173,216,230
lightcoral 亮珊瑚色 #f08080 240,128,128
lightcyan 亮青色 #e0ffff 224,255,255
lightgoldenrodyellow 亮金黄色 #fafad2 250,250,210
lightgray 亮灰色 #d3d3d3 211,211,211
lightgreen 亮绿色 #90ee90 144,238,144
lightgrey 亮灰色 #d3d3d3 211,211,211
lightpink 亮粉红色 #ffb6c1 255,182,193
lightsalmon 亮肉色 #ffa07a 255,160,122
lightseagreen 亮海蓝色 #20b2aa 32,178,170
lightskyblue 亮天蓝色 #87cefa 135,206,250
lightslategray 亮蓝灰 #778899 119,136,153
lightslategrey 亮蓝灰 #778899 119,136,153
lightsteelblue 亮钢兰色 #b0c4de 176,196,222
lightyellow 亮黄色 #ffffe0 255,255,224
lime 酸橙色 #00ff00 0,255,0
limegreen 橙绿色 #32cd32 50,205,50
linen 亚麻色 #faf0e6 250,240,230
magenta 红紫色 #ff00ff 255,0,255
maroon 粟色 #800000 128,0,0
mediumaquamarine 中绿色 #66cdaa 102,205,170
mediumblue 中兰色 #0000cd 0,0,205
mediumorchid 中粉紫色 #ba55d3 186,85,211
mediumpurple 中紫色 #9370db 147,112,219
mediumseagreen 中海蓝 #3cb371 60,179,113
mediumslateblue 中暗蓝色 #7b68ee 123,104,238
mediumspringgreen 中春绿色 #00fa9a 0,250,154
mediumturquoise 中绿宝石 #48d1cc 72,209,204
mediumvioletred 中紫罗兰色 #c71585 199,21,133
midnightblue 中灰兰色 #191970 25,25,112
mintcream 薄荷色 #f5fffa 245,255,250
mistyrose 浅玫瑰色 #ffe4e1 255,228,225
moccasin 鹿皮色 #ffe4b5 255,228,181
navajowhite 纳瓦白 #ffdead 255,222,173
navy 海军色 #000080 0,0,128
oldlace 老花色 #fdf5e6 253,245,230
olive 橄榄色 #808000 128,128,0
olivedrab 深绿褐色 #6b8e23 107,142,35
orange 橙色 #ffa500 255,165,0
orangered 红橙色 #ff4500 255,69,0
orchid 淡紫色 #da70d6 218,112,214
palegoldenrod 苍麒麟色 #eee8aa 238,232,170
palegreen 苍绿色 #98fb98 152,251,152
paleturquoise 苍宝石绿 #afeeee 175,238,238
palevioletred 苍紫罗兰色 #db7093 219,112,147
papayawhip 番木色 #ffefd5 255,239,213
peachpuff 桃色 #ffdab9 255,218,185
peru 秘鲁色 #cd853f 205,133,63
pink 粉红色 #ffc0cb 255,192,203
plum 洋李色 #dda0dd 221,160,221
powderblue 粉蓝色 #b0e0e6 176,224,230
purple 紫色 #800080 128,0,128
red 红色 #ff0000 255,0,0
rosybrown 褐玫瑰红 #bc8f8f 188,143,143
royalblue 皇家蓝 #4169e1 65,105,225
saddlebrown 重褐色 #8b4513 139,69,19
salmon 鲜肉色 #fa8072 250,128,114
sandybrown 沙褐色 #f4a460 244,164,96
seagreen 海绿色 #2e8b57 46,139,87
seashell 海贝色 #fff5ee 255,245,238
sienna 赭色 #a0522d 160,82,45
silver 银色 #c0c0c0 192,192,192
skyblue 天蓝色 #87ceeb 135,206,235
slateblue 石蓝色 #6a5acd 106,90,205
slategray 灰石色 #708090 112,128,144
slategrey 灰石色 #708090 112,128,144
snow 雪白色 #fffafa 255,250,250
springgreen 春绿色 #00ff7f 0,255,127
steelblue 钢兰色 #4682b4 70,130,180
tan 茶色 #d2b48c 210,180,140
teal 水鸭色 #008080 0,128,128
thistle 蓟色 #d8bfd8 216,191,216
tomato 西红柿色 #ff6347 255,99,71
turquoise 青绿色 #40e0d0 64,224,208
violet 紫罗兰色 #ee82ee 238,130,238
wheat 浅黄色 #f5deb3 245,222,179
white 白色 #ffffff 255,255,255
whitesmoke 烟白色 #f5f5f5 245,245,245
yellow 黄色 #ffff00 255,255,0

近期文章




Python网络爬虫与文本数据分析



bsite库 | 采集B站视频信息、评论数据


爬虫实战 | 采集&可视化知乎问题的回答



pdf2docx库 | 转文件格式,支持抽取文件中的表格数据


rpy2库 | 在jupyter中调用R语言代码

tidytext | 耳目一新的R-style文本分析库


reticulate包 | 在Rmarkdown中调用Python代码


plydata库 | 数据操作管道操作符>>


七夕礼物 | 全网最火的钉子绕线图制作教程


读完本文你就了解什么是文本分析


文本分析在经管领域中的应用概述


综述:文本分析在市场营销研究中的应用

plotnine: Python版的ggplot2作图库

小案例: Pandas的apply方法
  

stylecloud:简洁易用的词云库
 

用Python绘制近20年地方财政收入变迁史视频
  


Wow~70G上市公司定期报告数据集


漂亮~pandas可以无缝衔接Bokeh


YelpDaset: 酒店管理类数据集10+G







    分享



    ”和“



    在看



    ”是更好的支持

大邓和他的Python
我还没有学会写个人说明!
下一篇

Python绘制地图神器,上手直接开大!

你也可能喜欢

评论已经被关闭。

插入图片