- 内容提要
- 作者简介
- 技术评审者简介
- 致谢
- 译者序 会编程的人不一样
- 前言
- 本书的读者对象
- 编码规范
- 什么是编程
- 本书简介
- 下载和安装 Python
- 启动 IDLE
- 如何寻求帮助
- 聪明地提出编程问题
- 小结
- 第一部分 Python 编程基础
- 第1章 Python 基础
- 第2章 控制流
- 第3章 函数
- 第4章 列表
- 第5章 字典和结构化数据
- 第6章 字符串操作
- 第二部分 自动化任务
- 第7章 模式匹配与正则表达式
- 第8章 读写文件
- 第9章 组织文件
- 第10章 调试
- 第11章 从 Web 抓取信息
- 第12章 处理 Excel 电子表格
- 第13章 处理 PDF 和 Word 文档
- 第14章 处理 CSV 文件和 JSON 数据
- 第15章 保持时间、计划任务和启动程序
- 第16章 发送电子邮件和短信
- 第17章 操作图像
- 第18章 用 GUI 自动化控制键盘和鼠标
- 附录A 安装第三方模块
- 附录B 运行程序
- 附录C 习题答案
17.3 项目:添加徽标
假设你有一项无聊的工作,要调整数千张图片的大小,并在每张图片的角上增加一个小徽标水印。使用基本的图形程序,如Paintbrush或Paint,完成这项工作需要很长时间。像Photoshop这样神奇的应用程序可以批量处理,但这个软件要花几百美元。让我们写一个脚本来完成工作。
假定图 17-11 是要添加到每个图像右下角的标识:带有白色边框的黑猫图标,图像的其余部分是透明的。
图17-11 添加到图像中的徽标
总的来说,程序应该完成下面的事:
· 载入徽标图像。
· 循环遍历工作目标中的所有.png和.jpg文件。
· 检查图片是否宽于或高于300像素。
· 如果是,将宽度或高度中较大的一个减小为300像素,并按比例缩小的另一维度。
· 在角上粘贴徽标图像。
· 将改变的图像存入另一个文件夹。
这意味着代码需要做到以下几点:
· 打开catlogo.png文件作为Image对象。
· 循环遍历os.listdir('.')返回的字符串。
· 通过size属性取得图像的宽度和高度。
· 计算调整后图像的新高度和宽度。
· 调用resize()方法来调整图像大小。
· 调用paste()方法来粘贴徽标。
· 调用save()方法保存更改,使用原来的文件名。
第1步:打开徽标图像
针对这个项目,打开一个新的文件编辑器窗口,输入以下代码,并保存为resizeAndAddLogo.py:
#! python3 # resizeAndAddLogo.py - Resizes all images in current working directory to fit # in a 300x300 square, and adds catlogo.png to the lower-right corner. import os from PIL import Image ❶ SQUARE_FIT_SIZE = 300 ❷ LOGO_FILENAME = 'catlogo.png' ❸ logoIm = Image.open(LOGO_FILENAME) ❹ logoWidth, logoHeight = logoIm.size # TODO: Loop over all files in the working directory. # TODO: Check if image needs to be resized. # TODO: Calculate the new width and height to resize to. # TODO: Resize the image. # TODO: Add the logo. # TODO: Save changes.
在程序开始时设置SQUARE_FIT_SIZE❶和LOGO_FILENAME❷常量,这让程序以后更容易修改。假定你要添加的徽标不是猫图标,或者假定将输出图像的最大大小要减少的值不是300像素。有了程序开始时定义的这些常量,你可以打开代码,修改一下这些值,就大功告成了(或者你可以让这些常量的值从命令行参数获得)。没有这些常数,就要在代码中寻找所有的300和'catlogo.png',将它们替换新项目的值。总之,使用常量使程序更加通用。
徽标Image对象从Image.open()返回❸。为了增强可读性,logoWidth和logoHeight被赋予logoIm.size中的值❹。
该程序的其余部分目前是TODO注释,说明了程序的骨架。
第2步:遍历所有文件并打开图像
现在,需要找到当前工作目录中的每个PNG文件和.jpg文件。请注意,你不希望将徽标图像添加到徽标图像本身,所以程序应该跳过所有像LOGO_FILENAME这样的图像文件名。在程序中添加以下代码:
#! python3 # resizeAndAddLogo.py - Resizes all images in current working directory to fit # in a 300x300 square, and adds catlogo.png to the lower-right corner. import os from PIL import Image --snip-- os.makedirs('withLogo', exist_ok=True) # Loop over all files in the working directory. ❶ for filename in os.listdir('.'): ❷ if not (filename.endswith('.png') or filename.endswith('.jpg')) \ or filename == LOGO_FILENAME: ❸ continue # skip non-image files and the logo file itself ❹ im = Image.open(filename) width, height = im.size --snip--
首先,os.makedirs()调用创建了一个文件夹withLogo,用于保存完成的、带有徽标的图像,而不是覆盖原始图像文件。关键字参数exist_ok=True将防止os.makedirs()在withLogo已存在时抛出异常。在用os.listdir('.')遍历工作目录中的所有文件时❶,较长的if语句❷检查每个filename是否以.png或.jpg结束。如果不是,或者该文件是徽标图像本身,循环就跳过它,使用continue❸去处理下一个文件。如果filename确实以'.png'或'.jpg'结束(而且不是徽标文件),可以将它打开为一个Image对象❹,并设置width和height。
第3步:调整图像的大小
只在有宽或高超过SQUARE_FIT_SIZE时(在这个例子中,是300像素),该程序才应该调整图像的大小,所以将所有大小调整的代码放在一个检查width和height变量的if语句内。在程序中添加以下代码:
#! python3 # resizeAndAddLogo.py - Resizes all images in current working directory to fit # in a 300x300 square, and adds catlogo.png to the lower-right corner. import os from PIL import Image --snip-- # Check if image needs to be resized. if width > SQUARE_FIT_SIZE and height > SQUARE_FIT_SIZE: # Calculate the new width and height to resize to. if width > height: ❶ height = int((SQUARE_FIT_SIZE / width) * height) width = SQUARE_FIT_SIZE else: ❷ width = int((SQUARE_FIT_SIZE / height) * width) height = SQUARE_FIT_SIZE # Resize the image. print('Resizing %s...' % (filename)) ❸ im = im.resize((width, height)) --snip--
如果图像确实需要调整大小,就需要弄清楚它是太宽还是太高。如果width大于height,则高度应该根据宽度同比例减小❶。这个比例是当前宽度除以SQUARE_ FIT_SIZE的值。新的高度值是这个比例乘以当前高度值。由于除法运算符返回一个浮点值,而resize()要求的尺寸是整数,所以要记得将结果用int()函数转换成整数。最后,新的width值就设置为SQUARE_FIT_SIZE。
如果height大于或等于width(这两种情况都在else子句中处理),那么进行同样的计算,只是交换height和width变量的位置❷。
在width和height包含新图像尺寸后,将它们传入resize()方法,并返回的Image对象保存在im中❸。
第4步:添加徽标,并保存更改
不论图像是否调整大小,徽标仍应粘贴到右下角。徽标粘贴的确切位置取决于图像的大小和徽标的大小。图 17-12 展示了如何计算粘贴的位置。粘贴徽标的左坐标将是图像宽度减去徽标宽度,顶坐标将是图像高度减去徽标高度。
图17-12 在右下角放置徽标的左坐标和顶坐标,应该是图像的宽度/高度减去徽标宽度/高度
代码将徽标粘贴到图像中后,应保存修改后的Image对象。将以下代码添加到程序中:
#! python3 # resizeAndAddLogo.py - Resizes all images in current working directory to fit # in a 300x300 square, and adds catlogo.png to the lower-right corner. import os from PIL import Image --snip-- # Check if image needs to be resized. --snip-- # Add the logo. ❶ print('Adding logo to %s...' % (filename)) ❷ im.paste(logoIm, (width - logoWidth, height - logoHeight), logoIm) # Save changes. ❸ im.save(os.path.join('withLogo', filename))
新的代码输出一条消息,告诉用户徽标已被加入❶,将logoIm粘贴到im中计算的坐标处❷,并将变更保存到withLogo目录的filename中❸。如果运行这个程序,zophie.png文件是工作目录中唯一的图像,输出会是这样:
Resizing zophie.png... Adding logo to zophie.png...
图像zophie.png将变成225×300像素的图像,如图17-13所示。请记住,如果没有传入logoIm作为第三个参数,paste()方法不会粘贴透明的像素。这个程序可以在短短几分钟内自动调整几百幅图像,并“加上徽标”。
图17-13 图像zophie.png调整了大小并加上了徽标(左)。如果忘记了第三个参数,
徽标中透明的像素将被复制为不透明的白色像素(右)
第5步:类似程序的想法
能够批量合成图像或修改图像大小,在许多应用中都有用。可以编写类似的程序,完成以下任务:
· 为图像添加文字或网站URL。
· 为图像添加时间戳。
· 根据图像的大小,将图像复制或移动到不同的文件夹中。
· 为图像添加一个几乎透明的水印,防止他人复制。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论