Image模块
打开和新建
open(fp, mode)
fp
指文件路径,不存在抛出IOError
错误;
mode
是可选参数,表示文件打开方式,默认是r
可读。
new(mode, size, color=0)
该函数可以新建一个图像,其中mode
表示图像模式,size
表示图形大小,color
表示图形颜色,默认为黑色。具体图形模式查阅相关资料。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VuZMokdg-1667459490345)([外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NQZFgHO2-10-30-19-40-57-image.png2)(CMarkDownFiles%5CPyQt5Notes%5Cpic%5C2022-10-30-19-40-57-image.png#pic_center)]
)]
# 导入Pillow库
from PIL import Image
# 打开图片,返回实例对象
img1 = Image.open('PicLib/Pic1.jpg')
# 显示图片
img1.show()
# 查看图片属性
print("Pic1 的格式是 ", img1.format) # Pic1 的格式是 JPEG
print('Pic1 的大小是 ', img1.size) # Pic1 的大小是 (650, 433)
print('Pic1 的高度是 ', img1.height, ' Pic1 的宽度是 ', img1.width) # Pic1 的高度是 433 Pic1 的宽度是 650
print('Pic1在像素(150,300)的像素值是: ', img1.getpixel((150, 300))) # Pic1在像素(150,300)的像素值是: (61, 63, 62)
图像混合
透明度混合处理
blend(img1, img2, alpha)
其中,img1
和img2
分别是混合的两个图像,alpha
是混合透明度。混合的过程如下:(im1*(1-alpha)+im2*alpha)
,透明度主要作用在img2
上。
from PIL import Image
# 本地图片1
img1 = Image.open('PicLib/Pic1.jpg')
# 新建的图片,大小和本地图片一致,颜色为RGB元组
img2 = Image.new('RGB', img1.size, (35, 69, 85))
# 图像混合,简单的用透明度叠加,两幅影像都是0.5
blend_img = Image.blend(img1, img2, 0.5)
blend_img.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ATLkmXft-1667459490347)(I:\MarkDownFiles\PyQt5Notes\pic\2022-10-30-19-47-29-image.png)]
遮罩混合和通道分割
遮罩混合,蒙版罢了。
composite(img1, img2, mask)
img1
是上层的原始图层;
img2
是下层的叠加图层;
mask
是蒙版,蒙版的颜色程度决定了img2
的显示程度,我们以全黑的图层为例
from PIL import Image
img1 = Image.open('PicLib/Pic1.jpg') # 上层图层
img2 = Image.new('RGB', img1.size, (0, 0, 255)) # 三通道是蒙版
# 遮罩混合
img3 = Image.open('PicLib/Pic2.jpg') # 下层图层
img3.resize(img1.size)
r, g, b = img2.split()
composite_img = Image.composite(img1, img3, b)
composite_img.show()
以上代码为例,蒙版为全白图层,也就是没有进行任何修改,下层图像没有任何机会显示,全部显示上层图像。下面是图像大小的问题。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DmRyWJF2-1667459490347)(I:\MarkDownFiles\PyQt5Notes\pic\2022-10-30-20-18-53-image.png)]
我们将mask
修改为0时,img2 = Image.new('RGB', img1.size, (0, 0, 0))
。上层图像全部被研磨掉了,就只显示下层图像。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ExV7AcQ6-1667459490348)(I:\MarkDownFiles\PyQt5Notes\pic\2022-10-30-20-20-00-image.png)]
r, g, b = img2.split()
该函数可以将一个图像分割成RGB三个通道的颜色,如果是其他格式,如HIS或者CMYK可以分割成对应通道个数的影像。
如下代码,将图像转化成HSV格式,并分别输出三个通道的影像。
img1_convert = img1.convert(mode='HSV')
h,s,v = img1_convert.split()
h.show()
s.show()
v.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AOYkTVRM-1667459490349)(I:\MarkDownFiles\PyQt5Notes\pic\2022-10-30-20-23-07-image.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9gjXndMl-1667459490349)(I:\MarkDownFiles\PyQt5Notes\pic\2022-10-30-20-23-17-image.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6w2r0JRH-1667459490350)(I:\MarkDownFiles\PyQt5Notes\pic\2022-10-30-20-23-26-image.png)]
图像复制和缩放
Image.eval(img, fun)
该函数可以实现对图像像素值的处理,img
表示处理的图像,fun
是一个函数,该函数可以对每个通道的每个像元进行相同的操作。
from PIL import Image
img1 = Image.open('PicLib/Pic1.jpg')
img2 = Image.open('PicLib/Pic3.jpg')
print(img1.getpixel((150, 150))) # (121, 135, 148)
temp_img = Image.eval(img1, lambda x: x * 2)
print(temp_img.getpixel((150, 150))) # (242, 255, 255)
temp_img.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q8xkdt88-1667459490350)(I:\MarkDownFiles\PyQt5Notes\pic\2022-10-30-21-18-46-image.png)]
缩放为指定大小
img.thumbnail((width, height))
对图像直接进行缩放操作,会作用在源图像上,~~可以用该方法实现缩略图。~~大小变了,但是固定比例不变。
img3 = Image.open('PicLib/Pic3.jpg')
img3_temp = img3.copy()
img3_temp.thumbnail(img1.size)
print(img3_temp.size) # (650, 406)
img3_temp.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v0ZWx6n9-1667459490351)(I:\MarkDownFiles\PyQt5Notes\pic\2022-10-30-21-33-21-image.png)]
img.resize(width, height)
该函数可以直接缩放成固定长宽大小。
img3 = Image.open('PicLib/Pic3.jpg')
img3_temp = img3.copy()
img3_temp.thumbnail((50, 50))
print(img3_temp.size) # (50, 31)
img4 = img3.resize((50, 50))
print(img4.size) # (50, 50)
图像粘贴和裁剪
img.crop((4-tuple)
裁剪函数,有一个四元组的参数,指定四角边界点。
img.paste(paste-img, 2/4-tuple, mask)
粘贴函数,paste-img
表示粘贴的图片;有一个2或4元组,2元组表示左上点坐标,4元组表示四角边界点,默认为None
;mask
是遮罩图层,默认None
。
from PIL import Image
with Image.open('PicLib/Pic1.jpg') as img1:
# print(img1.histogram())
img_c1 = img1.copy()
img_crop = img_c1.crop((30, 30, 300, 300))
img_crop.show()
with Image.open('PicLib/Pic2.jpg') as img2:
img_c2 = img2.copy()
img_c2.paste(img_crop, (30, 30, 300, 300))
img_c2.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U58XxWAV-1667459490351)(I:\MarkDownFiles\PyQt5Notes\pic\2022-10-30-22-10-05-image.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lWuCu4hA-1667459490352)(I:\MarkDownFiles\PyQt5Notes\pic\2022-10-30-22-10-35-image.png)]
图像旋转和转置
img.rotate(angle,resample = 0,expand = 0,center = None,translate = None,fillcolor= None)
旋转函数作用于图像,有一点小问题,旋转后不影响图片的原有像素尺寸,但是周围的黑边并不知道是什么问题?无法使用resize
和crop
进行原有尺寸的修改。
-
rotate
返回影像的旋转副本; -
angle
是旋转角度; -
resample
是重采样的方式(线性插值、最近邻、三次卷积等,具体查看函数文档);expand
是可选扩展,为True
会自动去除黑边,并旋转为正常尺寸,否则就保留原有长宽尺寸,输出图像和输入图像大小相同; -
center
是水平旋转中心,2元组; -
translate
是前后旋转中心,2元组; -
fillcolor
是旋转后外部的填充颜色。
from PIL import Image
with Image.open('PicLib/Pic1.jpg') as img1:
# img1_temp_size = img1.resize((max_size, max_size))
img1_rotate = img1.rotate(90)
print(img1_rotate.size)
img1_rotate.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-McUihatB-1667459490352)(I:\MarkDownFiles\PyQt5Notes\pic\2022-10-31-11-08-28-image.png)]
img.transpose(const)
该函数实现图片的转置,相当于固定数值的rotate
。
-
PIL.Image.FLIP_LEFT_RIGHT
左右镜像; -
PIL.Image.FLIP_TOP_BOTTOM
上下镜像; -
PIL.Image.ROTATE_90
旋转90° -
PIL.Image.ROTATE_180
旋转180° -
PIL.Image.ROTATE_270
旋转270° -
PIL.Image.TRANSPOSE
颠倒顺序
with Image.open('PicLib/Pic2.jpg') as img2:
img2.transpose(method=Image.FLIP_TOP_BOTTOM).show()
但是以上方法在2023年将失效,他们把method
放进了Transpose
类中
from PIL import Image
from PIL.Image import Transpose
with Image.open('PicLib/Pic2.jpg') as img2:
img2.transpose(method=Transpose.TRANSPOSE).show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ou0OFXBa-1667459490352)(I:\MarkDownFiles\PyQt5Notes\pic\2022-10-31-12-02-05-image.png)]
图片格式转换
img.convert(mode,...)
mode
表示可以将图像转换成其他色彩空间的图像,mode = "L"
表示灰度图,还有RGB
和CMYK
,其他参数是辅助图像转换或其他空间特定转换的帮助参数。
from PIL import Image
with Image.open('PicLib/Pic1.jpg') as img1:
print(img1.mode) # RGB
# convert可以转换图像的色彩空间模式
img1.convert(mode='L').show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rtzNwehO-1667459490353)(I:\MarkDownFiles\PyQt5Notes\pic\2022-10-31-11-36-27-image.png)]
图像合并
Image.merge(mode, bands)
用多个单波段图像合成一副完整图像。mode
可以选择多种图像空间格式,bands
则是需要合成的图像波段,几个通道的图像空间就用几个单波段图像。
from PIL import Image
with Image.open('PicLib/Pic1.jpg') as img1:
R, G, B = img1.split()
# 单波段影像设置一个值
layer1 = Image.new('L', img1.size, 48)
layer2 = Image.new('L', img1.size, 168)
merge_pic = Image.merge('RGB', (R, layer1, layer2))
merge_pic.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SygyCEPI-1667459490353)(I:\MarkDownFiles\PyQt5Notes\pic\2022-10-31-12-18-12-image.png)]
滤镜
img.filter(const)
对图像添加滤镜,有几类预设滤镜,包含在ImageFilter
模块中。
-
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
from PIL import Image, ImageFilter
with Image.open('PicLib/Pic3.jpg') as img1:
# 模糊
img1.filter(ImageFilter.BLUR).show()
# 突出轮廓
img1.filter(ImageFilter.CONTOUR).show()
# 突出细节
img1.filter(ImageFilter.DETAIL).show()
# 边缘加强
img1.filter(ImageFilter.EDGE_ENHANCE).show()
img1.filter(ImageFilter.EDGE_ENHANCE_MORE).show()
# 浮雕 突出边缘
img1.filter(ImageFilter.EMBOSS).show()
# 突出边缘
img1.filter(ImageFilter.FIND_EDGES).show()
img1.filter(ImageFilter.SHARPEN).show()
img1.filter(ImageFilter.SMOOTH).show()
img1.filter(ImageFilter.SMOOTH_MORE).show()
其他内置属性和函数
内置属性
-
Image.format
显示图片格式 -
Image.mode
图片模式(RGB、CMYK等) -
Image.size
图片大小
内置函数
-
Image.getbands()
获取所有波段的名称,RGB格式的返回[R, G, B]; -
Image.getextrema()
获取每个波段的最大最小像元值,单波段返回2元组,多波段返回多元组; -
Image.getpixel(2-tuple)
给定2元组返回该像素值; -
Image.histogram(mask=None,extrema=None)
返回图像的直方图列表,多波段全部放在一个列表中; -
Image.point(function)
对每个像元执行一个函数; -
Image.putalpha(alpha)
给图像添加或修改alpha层(透明度层); -
Image.save(fp,format=None,**params)
保存图像; -
Image.show(title=None,command=None)
显示图像; -
Image.transform(size,method,data=None,resample=0,fill=1)
该方法时所有的
crop
、resize
等变换的根本方法,其他的变换方法都是对此方法的封装。size
表示新图片的大小;method
表示变换所用的方法;data
表示变化所需要的额外的数据;resample
表示重采样的方法;fill
表示滤波器;使用以上参数可以实现,截取原图像的一部分变换生成一个新图像(裁剪、缩放、旋转等);或者截取一个不规则四边形,重投影成一个矩形(QUAD)。
from PIL import Image from PIL.Image import Transform, Resampling with Image.open('PicLib/Pic3.jpg') as img: # 参数分别表示:新图像大小、8元组指定左上左下右上右下四角区域、变换方法(将四边形投影成矩形)、重采样方式 img.transform((200, 200), data=(15, 15, 15, 150, 360, 20, 360, 450), method=Transform.QUAD, resample=Resampling.BICUBIC).show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GEWlbd6F-1667459490354)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-01-10-05-54-image.png)]
-
Image.verify()
校验文件是否出现顺坏 -
Image.close()
关闭图像
ImageFilter模块
在该模块中除了上述的预定义模块,还有一些自定义模块
-
ImageFilter.GaussianBlur(2)
高斯噪声,参数为设置的噪声半径,可以实现图像的模糊化;
-
ImageFilter.BoxBlur(5)
方框滤波,一种快速滤波模糊的方法,参数设定半径;
-
ImageFilter.UnsharpMask(10, 200, 3)
USM锐化算法(虚光蒙版),参数分别为
radius
模糊半径、percent
锐化强度、threshold
控制锐化的最小亮度阈值,该方法可以增强图像高频部分,模糊抑制低频部分;[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jGrMIExS-1667459490354)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-01-10-29-09-image.png)]
-
ImageFilter.Kernel(size, kernel, scale, offset)
卷积核,对影像进行一个卷积滤波,
size
表示卷积核的大小,必须为3x3或5x5;kernel
是一个卷积核的权重序列;scale
是尺度因子;offset
偏置值,结果与偏置值相加。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AO94HPE5-1667459490354)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-01-10-32-50-image.png)]
img.filter(ImageFilter.Kernel((3, 3), (1, 2, 3, 1, 2, 3, 3, 2, 1), None, 15)).show()
-
ImageFilter.RankFilter(size, rank)
排序滤波,用一个
size*size
大小的滤波核进行排序,选择顺序为rank
的像元代替中心像元。这里设定size
为3,既卷积核为3x3;rank
为1,排序为第二个的像素代替中心像元。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9cBeuhr4-1667459490355)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-01-10-43-51-image.png)]
img.filter(ImageFilter.RankFilter(3, 1)).show()
-
ImageFilter.MedianFilter(size=3)
中值滤波,核的边长是3。
-
ImageFilter.MinFilter(size=3)
最小值滤波。
-
ImageFilter.MaxFilter(size=3)
最大值滤波。
-
ImageFilter.ModeFilter(size=3)
众数滤波,取核中出现次数最高的作为中心像元值;若都低于2次那就保留原来值。
-
ImageFilter.Filter
单波段滤波。
-
ImageFilter.MultibandFilter
多波段滤波。
ImageChops模块
channel operations
该模块包含了多个用于实现图片合成的函数。
这些合成功能是通过计算通道中像素值的方式来实现的。
其主要用于制作特效、合成图片等操作。
add图片相加
ImageChops.add(image1, image2, scale = 1.0, offset = 0)
该函数按照以下公式计算:
out = ((image1 + image2) / scale + offset)
from PIL import Image, ImageChops
with Image.open('PicLib/Pic1.jpg') as img1:
img2 = Image.new('RGB', img1.size, (60,60,12))
img_add = ImageChops.add(img1, img2, 1, 0)
img_add.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j3QAnmf5-1667459490355)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-01-11-17-50-image.png)]
当两幅完全不一样的影像相加时,会按照共同区域进行一个裁剪
with Image.open('PicLib/Pic1.jpg') as img1:
with Image.open('PicLib/Pic3.jpg') as img3:
img_add = ImageChops.add(img1, img3).show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pWaKqkWk-1667459490356)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-01-11-29-15-image.png)]
还有一个相加的方法
ImageChops.add_modulo(image1, image2)
?什么叫不剪切结果?
计算公式为:
out = ((image1 + image2) % MAX)
这个MAX
是合成后影像最大值还是之前的最大值?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RqGIJHwX-1667459490356)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-01-11-38-15-image.png)]
subtract图片相减
ImageChops.subtract(image1, image2, scale=1.0, offset=0)
和图片相加的原理一致。
ImageChops.subtract_modulo(image1, image2)
constant灰度图填充通道
ImageChops.constant(image, value)
填充之前图像是RGB模式,之后就成了单一通道的L模式。整个影像的灰度值是200.
from PIL import Image, ImageChops
with Image.open('PicLib/Pic1.jpg') as img:
gray_pic = ImageChops.constant(img, 200)
print(gray_pic.mode, img.mode) # L RGB
gray_pic.show()
linghter darker合成两幅影像的最小值和最大值——变暗和变亮函数
ImageChops.darker(image1, image2)
输入两幅影像,在重叠区域对比两个像元,取最小值形成一幅新的影像。
from PIL import Image,ImageChops
if __name__ == '__main__':
with Image.open('PicLib/Pic1.jpg') as img1:
with Image.open('PicLib/Pic3.jpg') as img3:
dark_img = ImageChops.darker(img1, img3)
dark_img.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-POkr9L7f-1667459490356)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-01-14-45-25-image.png)]
ImageChops.lighter(img1, img2)
道理和darker
函数一样。
multiply叠加函数
ImageChops.multiply(image1, image2)
叠加两幅影像,并不清楚和其他叠加有何区别?
out = image1 * image2 / MAX
from PIL import Image, ImageChops
if __name__ == '__main__':
with Image.open('PicLib/Pic1.jpg') as img1:
with Image.open('PicLib/Pic3.jpg') as img3:
layer_pic = Image.new("RGB", (800, 800), (200, 200, 200))
mult_pic = ImageChops.multiply(img1, layer_pic)
mult_pic.show()
screen屏幕函数
ImageChops.screen(img1, img2)
先反色后叠加。
out = MAX - ((MAX - image1) * (MAX - image2) / MAX)
invert反色函数
ImageChops.invert(img)
out = MAX - image
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FmwS4UnC-1667459490356)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-01-15-02-40-image.png)]
difference比较函数
ImageChops.difference(img1, img2)
比较两幅影像的像元值,做差后取绝对值,可以分析出影像的变化区域。
out = abs(image1 - image2)
其他内置函数
-
ImageChops.duplicate(image)
复制一个通道,相当于
copy
-
ImageChops.logical_and(image1, image2)
求两个影像的逻辑和,两幅影像必须是二值图
-
ImageChops.logical_or(image1, image2)
求逻辑或
-
ImageChops.logical_xor(image1, image2)
求逻辑非
-
ImageChops.soft_light
使用柔光算法叠加两幅影像
-
ImageChops.hard_light
硬光算法
-
ImageChops.overlay
叠加算法来叠加两幅影像
-
ImageChops.offset(image, xoffset, yoffset=None)
对一幅影像进行偏置计算,给定便宜的x和y距离,若只给出一个则两个采用相同值计算。移动了影像,四周进行移动运算。
with Image.open('PicLib/Pic3.jpg') as img3: ImageChops.offset(img3, 300,300).show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FvI0p41w-1667459490357)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-01-15-26-27-image.png)]
ImageEnhance模块
ImageEnhance
模块中包含多种增强影像效果的方法,可以用来调整影像的色彩、对比度、清晰度、亮度等。
在模块ImageEnhance
中,所有的图片增强对象都实现一个通用的接口。这个接口只包
含如下一个方法。
方法enhance()
会返回一个增强的Image
对象,参数factor
是一个大于0 的浮点数,1 表示返回原始图片。
当在Python
程序中使用模块ImageEnhance
增强图像效果时,需要首先创建对应的增强
调整器,然后调用调整器输出函数,根据指定的增强系数(小于1 表示减弱,大于1 表示增
强,等于1 表示原图不变)进行调整,最后输出调整后的图像。
也就是,ImageEnhance
的内置函数只是给一个套子并用enhancer
对象来代替,具体的加强效果或程度,则是之后的enhance(factor)
来表示。
from PIL import ImageEnhance, Image
with Image.open('PicLib/Pic3.jpg') as image:
enhancer = ImageEnhance.Sharpness(image)
for i in range(4, 8):
factor = i
enhancer.enhance(factor).show(f"Sharpness {factor:f}")
其中包含一些内置函数
Color色彩增强
利用该模块自带的色彩增强函数Color
对图像进行色彩增强
from PIL import Image, ImageEnhance
with Image.open('PicLib/Pic1.jpg') as img1:
# 新建一个区域,要放下平衡前后的两张图片
new_img = Image.new('RGB', ((img1.width + 5) * 3, img1.height))
# 粘贴原来的图片在左侧
new_img.paste(img1, (0, 0))
# 色彩增强图片
enhancer = ImageEnhance.Color(img1)
enhance_img1 = enhancer.enhance(5)
enhance_img2 = enhancer.enhance(10)
new_img.paste(enhance_img1, ((img1.width + 5) * 1, 0))
new_img.paste(enhance_img2, ((img1.width + 5) * 2, 0))
new_img.show()
在以上代码中,enhancer = ImageEnhance.Color(img1)
表示增强图片的挂钩,enhance_img1 = enhancer.enhance(5)
表示增强的因子。
该函数的形参,小于1表示衰减,1表示返回原图,大于1表示色彩增强。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yiZI1MNQ-1667459490357)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-02-21-20-58-image.png)]
Constrast对比度
与上诉的Color
的使用方法一致,enhancer = ImageEnhance.Contrast(img1)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ywstMMbl-1667459490357)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-02-21-26-27-image.png)]
Sharpness锐化
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zsVfPKNJ-1667459490358)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-02-21-28-00-image.png)]
Brightness亮度
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ab4HVZjl-1667459490358)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-02-21-28-42-image.png)]
ImageDraw模块
ImageDraw
模块实现了绘图功能。可以通过创建图片的方式来绘制2D 图像;
还可以在原有的图片上进行绘图,已达到修饰图片或对图片进行注释的目的。
绘制的结果是直接作用在原图上,如果需要保存结果则用save
该模块和图像增强模块一样,需要先给原图下个套。
draw.line绘制直线
ImageDraw.line(xy, fill=None, width=0, joint=None)
xy
表示一系列2元组,[(x1, y1), (x2, y2)...]
表示绘制的路径;
fill
表示线的颜色,可以输入元组表示颜色;
width
表示线宽;
joint='curve'
表示线之间的连接模式,据说这个是线之间的圆角,不知道怎么用?
from PIL import Image, ImageDraw
with Image.open("PicLib/Pic3.jpg") as im:
draw = ImageDraw.Draw(im)
draw.line([(0, 0), (200, 200), (400, 30), (600, 600), (700, 30)], fill=200, width=5, joint="curve")
draw.line((0, 0) + im.size, fill=(125, 125, 300), width=5)
draw.line((0, im.size[1], im.size[0], 0), fill=128)
im.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OBsylrJA-1667459490358)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-02-22-15-43-image.png)]
draw.arc绘制圆弧。
ImageDraw.arc(xy, start, end, fill=None, width=0)
xy
表示绘制的区域,是一个矩形的限制区域,可以用元组或者列表;
start
表示开始绘制的角度,默认0度,三点钟方向;
end
表示结束绘制的角度;
fill
可以用一个数字来代替三个数字。
draw = ImageDraw.Draw(im)
draw.arc((15, 15, 300, 300), 0, 210, 60, 3)
im.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2xg364eP-1667459490358)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-02-22-22-46-image.png)]
draw.ellipse绘制椭圆
ImageDraw.ellipse(xy, fill=None, outline=None, width=1)
xy
表示绘制的框体,若是个正方形绘制结果是个圆,其他矩形的结果是圆的拉伸;
fill
是填充的颜色;
outline
是框线的颜色。
draw = ImageDraw.Draw(im)
draw.ellipse([30,40,700,500], 60, 255, 5)
im.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yuH1EZOS-1667459490359)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-02-22-32-14-image.png)]
draw.chord绘制弦
ImageDraw.chord(xy, start, end, fill=None, outline=None, width=1)
绘制弦和绘制椭圆的参数一样,该函数时先绘制一个椭圆,之后对椭圆进行裁剪得到弦。
start
表示开始角度;
end
表示结束角度;
draw.chord(xy = [30,40,700,500], start=90, end=180, fill=60,outline=150,width=5)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IDsOtK2Y-1667459490359)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-02-22-38-02-image.png)]
draw.pieslice绘制扇形
ImageDraw.pieslice(xy, start, end, fill=None, outline=None, width=1)
绘制扇形和绘制弧一致。相当于从椭圆中截取固定角度形成扇形。
draw.pieslice(xy=((30, 40), (700, 500)), start=90, end=180, fill=60, outline=150, width=5)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jap8RUUz-1667459490359)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-03-09-17-12-image.png)]
draw.polygon绘制多边形
ImageDraw.polygon(xy, fill=None, outline=None, width=1)
xy
是一系列点,按照点的顺序进行绘制;
draw.polygon(xy=[(30, 40), (30, 500), (300, 100), (400, 600)], fill=(45, 65, 120), outline=(120, 120, 60), width=5)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ukh2vsLt-1667459490360)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-03-09-34-03-image.png)]
draw.rectangle绘制矩形
ImageDraw.rectangle(xy, fill=None, outline=None, width=1)
xy
只需要给个边框就行。
draw.rectangle(xy=[(30, 40),(400, 600)], fill=(45, 65, 120), outline=(120, 120, 60), width=5)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t66Vda9e-1667459490360)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-03-09-36-31-image.png)]
draw.rounded_rectangle绘制圆角矩形
ImageDraw.rounded_rectangle(xy,radius=0, fill=None, outline=None, width=1)
相比矩形多了一个radius
表示圆角的大小。
draw.rounded_rectangle(xy=[(30, 40),(400, 600)],radius=30 ,fill=(45, 65, 120), outline=(120, 120, 60), width=5)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ix17Er6X-1667459490360)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-03-09-38-05-image.png)]
draw.text绘制文字
ImageDraw.text(xy, text, fill=None, font=None, anchor=None, spacing=4, align='left', direction=None, features=None, language=None, stroke_width=0, stroke_fill=None, embedded_color=False)
在给定的位置绘制文字。
先导入ImageFont
模块,对于位图使用load
加载字体,其他格式使用truetype
具体参数参考文档。
ft = ImageFont.truetype('C:\\Windows\\Fonts\\STLITI.TTF', 60)
draw.text(xy=(150, 150), text="文字!!!", fill=(244, 241, 60), spacing=15, font=ft)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gSxzlC7G-1667459490361)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-03-09-54-27-image.png)]
ImageFont模块
该模块主要是一些常用的字体操作。
load
ImageFont.load(filename)
加载一个位图字体。
load_path
和load
方法一致,但是会多搜索一下python
目录下的位图字体。
truetype
ImageFont.truetype(font=None, size=10, index=0, encoding='', layout_engine=None)
加载一个TrueType
或OpenType
字体文件,并创建一个字体对象。默认加载当前目录下的文件,也会搜索Windows下的字体库。
size
是加载的文字大小;
index
要加载的字体顺序,默认是第一顺序;
encoding
编码方式,包含各类基本的编码方式,具体参看文档;
layout_engine
布局引擎。
具体实现见上一个例子。
load_default加载默认字体
ImageFont.load_default()
getSize
获取文本的宽度和高度。该方法将被取消。
getbbox
获取文本的四角边框。(left, top, right, bottom)
getlength
获取文字的长度
ft = ImageFont.truetype('C:\\Windows\\Fonts\\STLITI.TTF', 60)
draw.text(xy=(150, 150), text="文字!!!", fill=(244, 241, 60), spacing=15, font=ft)
print(ft.getbbox("文字!!!")) # (0, 8, 300, 52)
print(ft.getlength("文字!!!")) # 300.0
print(ft.getsize("文字!!!")) # 300, 52
不太能看懂getbbox
的范围,文字字体大小是60,文字间隔是15,应该是相对定位。
实例:绘制验证码
# -*- coding: utf-8 -*-
# 学习时间: 2022/11/3 10:37
__author__ = 'He XK'
import random
import string
from PIL import Image, ImageDraw, ImageFont, ImageFilter
# 新建验证码范围,设定背景颜色
background = Image.new('RGB', size=(150, 70), color='white')
def random_color(num1, num2):
return random.randint(num1, num2), random.randint(num1, num2), random.randint(num1, num2)
def random_text():
# 随机生成四位
# 包含大小写字母、数字
pre_list = []
for item in string.digits:
pre_list.append(item)
for item in string.ascii_letters:
pre_list.append(item)
result_list = random.sample(pre_list, 5)
return ''.join(result_list)
def random_place():
return random.randint(0, 30), random.randint(0, 20)
draw = ImageDraw.Draw(background)
ft = ImageFont.truetype('C:\\Windows\\Fonts\\Deng.TTF', 40)
for i in range(background.width):
for j in range(background.height):
draw.point(xy=(i, j), fill=random_color(100, 160))
draw.text(xy=random_place(), text=random_text(), fill=(random_color(180, 220)), font=ft, spacing=15)
background.filter(ImageFilter.BoxBlur(5))
background.show()
random_color
生成一个随机颜色
random_text
生成一个包含大小写字母和数字的5字符文本
string.digits
可以生成所有的数字
string.ascii_letters
可以生成所有的字母
random.sample(pre_list, 5)
可以从列表中随机获取指定个数的元素
random_place
生成一个随机位置,用于移动text文本
像素赋值
for i in range(background.width):
for j in range(background.height):
draw.point(xy=(i, j), fill=random_color(100, 160))
使用point
函数给背景图的每一个像素填充随机颜色
添加文本
draw.text(xy=random_place(), text=random_text(), fill=(random_color(180, 220)), font=ft, spacing=15)
background.filter(ImageFilter.BoxBlur(5))
添加随机文本,赋予随机颜色和随机的初始位置,位置不太能分清和字体大小的相对关系。并添加一个模糊滤镜。最后如果保存可以用save
。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E4FnGxRI-1667459490361)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-03-15-10-31-image.png)]
ge(background.width):
for j in range(background.height):
draw.point(xy=(i, j), fill=random_color(100, 160))
draw.text(xy=random_place(), text=random_text(), fill=(random_color(180, 220)), font=ft, spacing=15)
background.filter(ImageFilter.BoxBlur(5))
background.show()
### random_color
生成一个随机颜色
## random_text
生成一个包含大小写字母和数字的5字符文本
`string.digits`可以生成所有的数字
`string.ascii_letters`可以生成所有的字母
`random.sample(pre_list, 5)`可以从列表中随机获取指定个数的元素
## random_place
生成一个随机位置,用于移动text文本
## 像素赋值
```python
for i in range(background.width):
for j in range(background.height):
draw.point(xy=(i, j), fill=random_color(100, 160))
使用point
函数给背景图的每一个像素填充随机颜色
添加文本
draw.text(xy=random_place(), text=random_text(), fill=(random_color(180, 220)), font=ft, spacing=15)
background.filter(ImageFilter.BoxBlur(5))
添加随机文本,赋予随机颜色和随机的初始位置,位置不太能分清和字体大小的相对关系。并添加一个模糊滤镜。最后如果保存可以用save
。