返回介绍

17.3 项目:添加徽标

发布于 2024-01-22 21:44:06 字数 5941 浏览 0 评论 0 收藏 0

假设你有一项无聊的工作,要调整数千张图片的大小,并在每张图片的角上增加一个小徽标水印。使用基本的图形程序,如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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文