Pillow学习笔记

Pillow (PIL Fork) 9.3.0 documentation

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)

其中,img1img2分别是混合的两个图像,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元组表示四角边界点,默认为Nonemask是遮罩图层,默认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)

旋转函数作用于图像,有一点小问题,旋转后不影响图片的原有像素尺寸,但是周围的黑边并不知道是什么问题?无法使用resizecrop进行原有尺寸的修改。

  1. rotate返回影像的旋转副本;

  2. angle是旋转角度;

  3. resample是重采样的方式(线性插值、最近邻、三次卷积等,具体查看函数文档);expand是可选扩展,为True会自动去除黑边,并旋转为正常尺寸,否则就保留原有长宽尺寸,输出图像和输入图像大小相同;

  4. center是水平旋转中心,2元组;

  5. translate是前后旋转中心,2元组;

  6. 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

  1. PIL.Image.FLIP_LEFT_RIGHT 左右镜像;

  2. PIL.Image.FLIP_TOP_BOTTOM 上下镜像;

  3. PIL.Image.ROTATE_90 旋转90°

  4. PIL.Image.ROTATE_180 旋转180°

  5. PIL.Image.ROTATE_270 旋转270°

  6. 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"表示灰度图,还有RGBCMYK,其他参数是辅助图像转换或其他空间特定转换的帮助参数。
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模块中。

  1. ImageFilter.BLUR模糊

  2. ImageFilter.CONTOUR突出轮廓

  3. ImageFilter.DETAIL加强细节

  4. ImageFilter.EDGE_ENHANCE增强边缘

  5. ImageFilter.EDGE_ENHANCE_MORE

  6. ImageFilter.EMBOSS浮雕,突出边缘

  7. ImageFilter.FIND_EDGES查找边缘

  8. ImageFilter.SHARPEN锐化

  9. ImageFilter.SMOOTH平滑

  10. 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()

其他内置属性和函数

内置属性

  1. Image.format显示图片格式

  2. Image.mode图片模式(RGB、CMYK等)

  3. Image.size图片大小

内置函数

  1. Image.getbands()获取所有波段的名称,RGB格式的返回[R, G, B];

  2. Image.getextrema()获取每个波段的最大最小像元值,单波段返回2元组,多波段返回多元组;

  3. Image.getpixel(2-tuple)给定2元组返回该像素值;

  4. Image.histogram(mask=None,extrema=None)返回图像的直方图列表,多波段全部放在一个列表中;

  5. Image.point(function)对每个像元执行一个函数;

  6. Image.putalpha(alpha)给图像添加或修改alpha层(透明度层);

  7. Image.save(fp,format=None,**params)保存图像;

  8. Image.show(title=None,command=None)显示图像;

  9. Image.transform(size,method,data=None,resample=0,fill=1)

    该方法时所有的cropresize等变换的根本方法,其他的变换方法都是对此方法的封装。

    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)]

  10. Image.verify()校验文件是否出现顺坏

  11. Image.close()关闭图像


ImageFilter模块

在该模块中除了上述的预定义模块,还有一些自定义模块

  1. ImageFilter.GaussianBlur(2)

    高斯噪声,参数为设置的噪声半径,可以实现图像的模糊化;

  2. ImageFilter.BoxBlur(5)

    方框滤波,一种快速滤波模糊的方法,参数设定半径;

  3. ImageFilter.UnsharpMask(10, 200, 3)

    USM锐化算法(虚光蒙版),参数分别为radius模糊半径、percent锐化强度、threshold控制锐化的最小亮度阈值,该方法可以增强图像高频部分,模糊抑制低频部分;

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jGrMIExS-1667459490354)(I:\MarkDownFiles\PyQt5Notes\pic\2022-11-01-10-29-09-image.png)]

  4. 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()
    
  5. 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()
    
  6. ImageFilter.MedianFilter(size=3)

    中值滤波,核的边长是3。

  7. ImageFilter.MinFilter(size=3)

    最小值滤波。

  8. ImageFilter.MaxFilter(size=3)

    最大值滤波。

  9. ImageFilter.ModeFilter(size=3)

    众数滤波,取核中出现次数最高的作为中心像元值;若都低于2次那就保留原来值。

  10. ImageFilter.Filter

    单波段滤波。

  11. 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)

其他内置函数

  1. ImageChops.duplicate(image)

    复制一个通道,相当于copy

  2. ImageChops.logical_and(image1, image2)

    求两个影像的逻辑和,两幅影像必须是二值图

  3. ImageChops.logical_or(image1, image2)

    求逻辑或

  4. ImageChops.logical_xor(image1, image2)

    求逻辑非

  5. ImageChops.soft_light

    使用柔光算法叠加两幅影像

  6. ImageChops.hard_light

    硬光算法

  7. ImageChops.overlay

    叠加算法来叠加两幅影像

  8. 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)

加载一个TrueTypeOpenType字体文件,并创建一个字体对象。默认加载当前目录下的文件,也会搜索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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值