pillow学习
支持文件
Image类
操作图片
打开图片open()
from PIL import Image
im = Image.open('图片测试.gif')
#查看图片属性
print(im.format,im.size,im.mode)
print(im.format, "%dx%d" % im.size, im.mode)
E:\study\venv3\Scripts\python.exe E:/study/输入与输出/day01.py
GIF (292, 213) P
GIF 292x213 P
mode相关知识:电脑中的图像模式类型,PIL中PIL.Image.new的model类型
show() 展示图片
目前遇到一个问题,展示的gif图不会动。延后解决。
save()保存图片
Image模块中的save()函数可以保存图片,如果save的第二个参数不写,将会根据文件名来保存相应格式的文件。如果文件名中没有给出一个标准的图像格式,那么第二个参数必须要有。
图片转成jpg格式
ifrom PIL import Image
import os,sys
#os.path.splitext(“文件路径”) 分离文件名与扩展名;默认返回(fname,fextension)元组,可做分片操作
fname,fextension = os.path.splitext('E:\study\白色.png')
newname = fname + '.jpg'
im = Image.open("白色.png")
im.save(newname)
这里会出现OSError: cannot write mode RGBA as JPEG的问题,因为图片的mode不一致。
解决方法:使用PIL模块存储图像时的报错:cannot write mode P as JPEG
图片
from PIL import Image
im = Image.open("timg.jpg")
print(im.size,im.mode)
im.thumbnail((20,20))
#thunbnail的略缩图参数一个元祖
im.save('E:\study\输入与输出\白色.thumbnail',"JPEG")
这里也会出现不同mode不能转换的问题,同时弄出来的图片名字为白色.thumbnail,没有带JPEG了。
复制、裁剪、粘贴图片、换位
copy()、crop()、transpose()、paste()
一、复制并保存图像
from PIL import Image
im = Image.open('图片测试.gif')
box = im.copy()
box.save('hi.jpg',"GIF")
二、裁剪指定区域图像
from PIL import Image
im = Image.open('图片测试.gif')
#crop参数是元祖类型,坐标为(左,上,右,下)
box = (0,0,50,70)
im.crop(box).save('hi.jpg',"GIF")
三、将图像旋转180度
from PIL import Image
im = Image.open('图片测试.gif')
box = (0,0,100,100)
im = im.crop(box)
im = im.transpose(Image.ROTATE_180)
im.show()
常量 | 作用 |
---|---|
Image.FILP_TOP_BOTTOM | 上下翻转 |
Image.FILP_LEFT_RIGHT | 左右翻转 |
Image.ROTATE_90 | 翻转90° |
Image.ROTATE_180 | 翻转180° |
Image.TRANSPOSE | 颠倒 |
四、粘贴
paste(im, box, mask),
其中im为Image对象;box为要粘贴到的区域;mask为遮罩(我也不知道啥是遮罩,留个坑位)。
其中box的参数有三种形式:
(x1, y1):将im左上角对齐(x1,y1)点,其余部分粘贴,超出部分抛弃
(x1, x2, y1, y2):将im粘贴至此区域 注意:此参数要与需粘贴的图片大小参数一致
None:相当于(0,0)可能还有其它作用暂时未知。
from PIL import Image
#被粘贴的图片
im = Image.open('白色.jpg')
#粘贴的图片
ih = Image.open('hi.jpg')
box = (0,0)
im.paste(ih,box)
im.show()
踩过的坑使用im.paste(ih,box).show() 这里的对象都不一样了,说一会出现没有show属性的错误。
滚动的图像
from PIL import Image
def roll(image, delta):
"""Roll an image sideways."""
xsize, ysize = image.size
#取余,如果余数等于零直接返回图像
while delta != 0:
delta = delta % xsize
print(delta)
if delta == 0: return image
else:
#对图片进行截取,截取的坐标为左侧delta宽的地方。
part1 = image.crop((0, 0, delta, ysize))
#对图片进行截取,截取的坐标为右侧x-delta的地方
part2 = image.crop((delta, 0, xsize, ysize))
#粘贴图片把part1截取的图粘贴到右边
image.paste(part1, (xsize-delta, 0, xsize, ysize))
#把图片粘贴到左边
image.paste(part2, (0, 0, xsize-delta, ysize))
image.show()
if __name__ == '__main__':
im = Image.open('timg.jpg')
roll(im,40)
拆分和合并波段
不懂什么原理,留坑
from PIL import Image
im = Image.open('timg.jpg')
print(im.mode)
r,g,b = im.split()
im = Image.merge('RGB',(b,g,r))
im.show()
运行前 运行后
简单的几何变换
改变图片大小
from PIL import Image
im = Image.open('timg.jpg')
out = im.resize((128,128))
旋转
有些功能transpose()也能使用,见上面。
from PIL import Image
im = Image.open('timg.jpg')
out = im.rotate(45)
out.show()
相似图片对比,来源于网络
from PIL import Image
import math
import operator
from functools import reduce
def image_contrast(img1, img2):
image1 = Image.open(img1)
image2 = Image.open(img2)
#返回图片直方图,用列表的形式存储的
h1 = image1.histogram()
h2 = image2.histogram()
#lambda [arg1 [,arg2,.....argn]]:expression
#map()函数map() 会根据提供的函数对指定序列做映射。
#第一个参数 function 以参数序列中的每一个元素调用 function 函数,
# 返回包含每次 function 函数返回值的新列表。python3 返回的是迭代器,所以需要转换为列表。
#reduce() 函数语法:
# reduce(function, iterable[, initializer])
# 参数
# function -- 函数,有两个参数
# iterable -- 可迭代对象
# initializer -- 可选,初始参数
result = math.sqrt(reduce(operator.add, list(map(lambda a, b: (a - b) ** 2, h1, h2))) / len(h1))
return result
if __name__ == '__main__':
img1 = "./picture/相似图片01.png" # 指定图片路径
img2 = "./picture/相似图片02.png"
img3 = "./picture/相似图片03.png"
result1 = image_contrast(img1, img2)
result2 = image_contrast(img1, img3)
print(result1,result2)