Python工具箱系列(五十)
使用PIL加工图片
常见的图片操作包括但不限于:
•大小进行变化
•旋转
•翻转
•使用滤镜进行处理
•剪切
以下python代码演示了如何将一幅美女图进行多种加工处理,并且汇集在一起,形成一个类似于照片墙的相关操作。
from PIL import Image
from PIL import ImageFilter
from PIL import ImageEnhance
from PIL import ImageDraw, ImageFont
import math
def text(image, text):
"""
给图片加上文字
truetype设置字体、文字大小
stxingka.ttf华文行楷 simkai.ttf 楷体 simli.ttf 隶书
Args:
image (object): 图片对象
text (string): 要加入的文字
"""
draw = ImageDraw.Draw(image)
font = ImageFont.truetype("C:\\WINDOWS\\Fonts\\simkai.ttf", 80)
draw.text((50, 200), (text), fill='#0000ff', font=font)
def gallery(inputfilename, outputfilename,cols=3):
"""
做一个图片墙
Args:
inputfilename (string): 输入文件名称
outputfilename (string): 输出文件名称
cols(int): 显示的列数。缺省是3列显示
"""
filters = [ImageFilter.BLUR, ImageFilter.CONTOUR, ImageFilter.DETAIL, ImageFilter.EDGE_ENHANCE, ImageFilter.EDGE_ENHANCE_MORE,
ImageFilter.EMBOSS, ImageFilter.FIND_EDGES, ImageFilter.SHARPEN, ImageFilter.SMOOTH, ImageFilter.SMOOTH_MORE]
filtername = ['ImageFilter.BLUR', 'ImageFilter.CONTOUR', 'ImageFilter.DETAIL', 'ImageFilter.EDGE_ENHANCE', 'ImageFilter.EDGE_ENHANCE_MORE',
'ImageFilter.EMBOSS', 'ImageFilter.FIND_EDGES', 'ImageFilter.SHARPEN', 'ImageFilter.SMOOTH', 'ImageFilter.SMOOTH_MORE']
imglist = list()
# 原图
im = Image.open(inputfilename)
# 计算缩放比例
imagewidth, imageheight = im.size
# 以宽为标准进行缩。
targetwidth = math.floor(1920/cols)
rate = targetwidth/imagewidth
targetheight = math.ceil(imageheight*rate)
out = im.copy()
text(out, "原图")
imglist.append(out)
# 旋转
out = im.copy().rotate(45)
text(out, '旋转45度')
imglist.append(out)
# 对称翻转
out = im.copy().transpose(Image.Transpose.FLIP_LEFT_RIGHT)
text(out, '对称翻转')
imglist.append(out)
# 加滤镜
for fi, name in zip(filters, filtername):
out = im.filter(fi)
text(out, name)
imglist.append(out)
# 强化对比
enh = ImageEnhance.Contrast(im)
out = enh.enhance(1.3)
text(out, 'enhanced')
imglist.append(out)
# cut
box = (500, 400, 900, 800)
out = im.crop(box)
text(out, 'cut')
imglist.append(out)
# 水平排列
count = len(imglist)
if count % cols == 0:
rows = count // cols
else:
rows = count // cols + 1
new_width = 1920
new_height = math.ceil(rows * targetheight)
final = Image.new('RGB', (new_width, new_height))
for row in range(rows):
for col in range(cols):
index = row*cols+col
if index < count:
img = imglist[row*cols+col]
width, _ = img.size
if width > targetwidth:
out = img.resize((targetwidth, targetheight))
else:
out = img
final.paste(out, (col * targetwidth, row * targetheight))
final.save(outputfilename)
gallery(r'd:\test\girl.png',r'd:\test\gallery.png')
运行后的效果如下图所示。
在这个照片墙上,每种加工的名称都输出到图片的左上侧。 最后一个图是剪切图,小于照片墙预留的空间,所以显得奇怪一些。