17.3 项目:添加徽标

假设你有一项无聊的工作,要调整数千张图片的大小,并在每张图片的角上增
加一个小徽标水印。使用基本的图形程序,如Paintbrush 或Paint,完成这项工作需要很长时间。像 Photoshop 
这样神奇的应用程序可以批量处理,但这个软件要花几百美元。让我们写一个脚本来完成工作。
假定图 17-11 是要添加到每个图像右下角的标识:带有白色边框的黑猫图标,图像的其余部分是透明的。
17.3 项目:添加徽标总的来说,程序应该完成下面的事:
•    载入徽标图像。
•    循环遍历工作目标中的所有.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 中➌。17.3 项目:添加徽标

图 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.3 项目:添加徽标

 

 

第 4 步:添加徽标,并保存更改
不论图像是否调整大小,徽标仍应粘贴到右下角。徽标粘贴的确切位置取决于图像的大小和徽标的大小。图 17-12 
展示了如何计算粘贴的位置。粘贴徽标的左坐标将是图像宽度减去徽标宽度,顶坐标将是图像高度减去徽标高度。

第 5 步:类似程序的想法
能够批量合成图像或修改图像大小,在许多应用中都有用。可以编写类似的程序,完成以下任务:
•    为图像添加文字或网站 URL。
•    为图像添加时间戳。

•    根据图像的大小,将图像复制或移动到不同的文件夹中。
•    为图像添加一个几乎透明的水印,防止他人复制。
 

上一篇:Cocos2dLua3.17.2集成FairyGUI之 lua绑定 setHook()回调问题(四)


下一篇:CSS 垂直居中的正确打开方式