zoukankan      html  css  js  c++  java
  • ❤️【Python从入门到精通】(二十七)更进一步的了解Pillow吧!

    您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦
    进一步介绍Pillow库的使用,详细了解
    干货满满,建议收藏,需要用到时常看看。 小伙伴们如有问题及需要,欢迎踊跃留言哦~ ~ ~。

    前言

    本文是接上一篇❤️【Python从入门到精通】(二十六)用Python的PIL库(Pillow)处理图像真的得心应手❤️ 进一步介绍Pillow库的使用,本文将重点介绍一些高级特性:比如如何利用Pillow画图形(圆形,正方形),介绍通过Pillow库给图片添加水印;同时对上一篇文章未介绍的常用知识点进行补充说明。希望对读者朋友们有所帮助。

    Image模块

    上一篇文章已经介绍了Image模块,但是介绍的还不够全面,例如如何从网页中读取图片没有介绍到,如何裁剪图片都没有介绍到。

    读取网页中的图片

    读取网页中的图片的基本实现方式是:首先利用requests库读取当前图片链接的内容,接着将内容转成二进制数据,在通过open方法将该二进制数据,最后通过save方法进行保存。

    from PIL import Image
    from io import BytesIO
    import requests
    # 读取网页图片
    res = requests.get(
        'https://img-blog.csdnimg.cn/f2e98e08d5ec4283b08972c5ee8e1689.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA56CB5Yac6aOe5ZOl,size_20,color_FFFFFF,t_70,g_se,x_16').content
    #将图片内容转成二进制
    im2 = Image.open(BytesIO(res))
    b = BytesIO()
    im2.save(b, format='PNG')
    im2.show()
    

    读取结果是:
    在这里插入图片描述

    图片裁剪

    通过crop方法可以从图片中裁剪出一个指定大小的区域。裁取的区域范围是(left, upper, right, lower) 比如从某个宽高都是400的图片中裁剪一个是宽高都是100的正方形区域,只需要指定裁剪区域的坐标是: (0, 0, 100, 100)

    im2 = Image.new('RGBA', (400, 400), 'blue')
    box = (0, 0, 100, 100)
    region = im2.crop(box)  # 设置要裁剪的区域
    region.show()
    

    有裁剪还有一个方法就是重新设置图片大小的方法 resize,比如将前面400400的图片 修改成 300200,只需要调用resize方法

    img4 = im2.resize((300, 200))
    img4.show()
    

    图片模式的说明:

    模式 描述
    1 1位像素,黑白图像,存成8位像素
    L 8位像素,黑白
    P 8位像素,使用调色板映射到任何其他模式
    RGB 3*8位像素,真彩
    RGBA 4*8 位像素,真彩+透明通道
    CMYK 4*8位像素,印刷四色模式或彩色印刷模式
    YCbCr 3*8位像素,色彩视频格式
    I 32位整型像素
    F 33位浮点型像素

    通过 convert方法进行图片模式的转换

    ImageDraw模块

    前面介绍的ImageDraw库,只是介绍了利用它来向图片写入文本,其实ImageDraw模块还有一个更有用的途径,就是可以通过它来画各种图形。

    画图的方法介绍

    方法 示范 作用
    ImageDraw.line(xy, fill=None, width=0, joint=None) draw.line([100, 100, 100, 500], fill='blue', width=2) 画正方形
    ImageDraw.arc(xy, start, end, fill=None, width=1) draw.arc([100, 100, 600, 600], 0, 360, fill='black') 画弧形
    ImageDraw.ellipse(xy, fill=None, outline=None, width=1) draw.ellipse([100, 100, 600, 600], outline='black', fill='white') 画圆
    ImageDraw.chord(xy, start, end, fill=None, outline=None, width=1) draw.chord([100, 100, 600, 600], 0, 360, outline=125) 画半圆,类似于arc()
    ImageDraw.pieslice(xy, start, end, fill=None, outline=None, width=1) draw.pieslice([100, 100, 600, 600], 180, 210, outline=255) 画扇形
    ImageDraw.rectangle(xy, fill=None, outline=None, width=1) draw.rectangle((200, 200, 500, 500), outline='yellow') 画矩形
    ImageDraw.rounded_rectangle(xy, radius=0, fill=None, outline=None, width=1) draw.rounded_rectangle((200, 200, 600, 600), radius=1, outline='green') 画圆角矩形(或正方形)

    画正方形

    首先创建一个600*600的画布。然后再画布中画出一个正方形,画直线的方法是 line方法。
    ImageDraw.line(xy, fill=None, width=0, joint=None)

    在xy的坐标之间画一条直线
    xy--> 在两个坐标点之间画一条直线,坐标点的传入方式是[(x, y), (x, y), ...]或者[x, y, x, y, ...]
    fill--> 直线的颜色
    width--> 直线的宽度

    # 画点
    im = Image.new('RGB', (600, 600), 'white')
    draw = ImageDraw.Draw(im)
    
    # # 创建一个正方形,fill 代表的为颜色
    draw.line([100, 100, 100, 500], fill='blue', width=2)  # 左竖线
    draw.line([100, 100, 500, 100], fill='blue', width=2)  # 上横线
    draw.line([500, 100, 500, 500], 'blue', width=2) #右竖线
    draw.line([100, 500, 500, 500], 'blue', width=2) #下横线
    im.save('picture/sequare.png', 'png')
    im.show()
    

    画一个边框宽度为2px,颜色为蓝色的,面积为400*400的正方形。
    在这里插入图片描述

    画弧形

    ImageDraw.arc(xy, start, end, fill=None, width=0)

    在给定的区域范围内,从开始角到结束角之间绘制一条圆弧
    xy--> 定义边界框的两个点,传入的格式是[(x0, y0), (x1, y1)] 或者 [x0, y0, x1, y1] ,其中 x1>=x0,y1>=y0
    start --> 起始角度,以度为单位,从3点钟开始顺时针增加
    end--> 结束角度,以度为单位
    fill--> 弧线的颜色
    width-->弧线的宽度

    draw.arc([100, 100, 600, 600], 0, 180, fill='black')
    im.show()
    

    在这里插入图片描述
    这里就是画了一个半圆,如果结束角度是360度的话则就会画一个完整的圆。

    画圆

    画圆通过ImageDraw.ellipse(xy, fill=None, outline=None, width=1) 方法,该方法可以画出一个给定范围的圆

    xy--> 定义边界框的两个点,传入的格式是[(x0, y0), (x1, y1)] 或者 [x0, y0, x1, y1] ,其中 x1>=x0,y1>=y0
    outline--> 轮廓的颜色
    fill ---> 填充颜色
    width--> 轮廓的宽度

    draw.ellipse([100, 100, 600, 600], outline='black', fill='blue')
    im.show()
    

    在这里插入图片描述

    画半圆

    ImageDraw.chord(xy, start, end, fill=None, outline=None, width=1) 方法用来画半圆,跟arc()方法不同的是它会用直线将起始点和结束点连接起来

    xy--> 定义边界框的两个点,传入的格式是[(x0, y0), (x1, y1)] 或者 [x0, y0, x1, y1] ,其中 x1>=x0,y1>=y0
    outline--> 轮廓的颜色
    fill ---> 填充颜色
    width--> 轮廓的宽度

    draw.chord([100, 100, 600, 600], 0, 180,  outline='black', fill='red')
    im.show()
    

    在这里插入图片描述

    画扇形

    ImageDraw.pieslice(xy, start, end, fill=None, outline=None, width=1)
    类似于arc()方法,不过他会在端点和圆点之间画直线
    xy--> 定义边界框的两个点,传入的格式是[(x0, y0), (x1, y1)] 或者 [x0, y0, x1, y1] ,其中 x1>=x0,y1>=y0
    start --> 起始角度,以度为单位,从3点钟开始顺时针增加
    end--> 结束角度,以度为单位
    fill--> 弧线的颜色
    width-->弧线的宽度

    draw.pieslice([100, 100, 600, 600], 180, 300, outline='red', fill='blue')
    im.show()
    

    在这里插入图片描述

    画矩形

    ImageDraw.rectangle(xy, fill=None, outline=None, width=1)
    xy--> 在两个坐标点之间画一条直线,坐标点的传入方式是[(x, y), (x, y), ...]或者[x, y, x, y, ...]
    outline--> 轮廓的颜色
    fill--> 填充的颜色
    width--> 轮廓线的宽度

    # 矩形
    draw.rectangle((100, 200, 300, 500), outline='red', fill='blue')
    im.show()
    

    在这里插入图片描述

    画圆角矩形

    ImageDraw.rounded_rectangle(xy, radius=0, fill=None, outline=None, width=1) 该方法可以画一个圆角矩形
    xy--> 在两个坐标点之间画一条直线,坐标点的传入方式是[(x, y), (x, y), ...]或者[x, y, x, y, ...]
    radius--> 角的半径
    outline--> 轮廓的颜色
    fill--> 填充的颜色
    width--> 轮廓线的宽度

    draw.rounded_rectangle((200, 200, 600, 600), radius=2, outline='green')
    im.show()
    

    在这里插入图片描述

    解决一个问题

    这里有个问题,就是画好的图形如何从Image中扣出来呢?

    ImageEnhance模块

    ImageEnhance模块主要是用于设置图片的颜色对比度亮度锐度等啥的,增强图像。

    1. 原图
    from PIL import ImageEnhance, Image
    
    org_img = Image.open('picture/img10.png')
    org_img.show(title='原图')
    

    原始图像
    在这里插入图片描述

    1. 图像的颜色平衡,颜色增强1.2倍
      PIL.ImageEnhance.Color(image) 方法,这个方法主要用于调整图像的色彩平衡,原始图像的系数是1.0,0.0的增强系数得到的是一个黑白图像
    cl = ImageEnhance.Color(org_img)
    #黑白图像
    ce = cl.enhance(0)
    ce.show()
    #增强1.2倍
    ce1 = cl.enhance(1.2)
    ce1.show()
    

    在这里插入图片描述

    1. 调整图像的对比度 3:4
      PIL.ImageEnhance.Contrast(image)该方法主要用于调整图像的对比度,类似于电视机上的对比度控制,0.0的增强系数给出的是一个纯灰色图像,系数1.0则得到原始图像
    ct = ImageEnhance.Contrast(org_img)
    ch = ct.enhance(0)
    ch.show(title='对比度0纯灰色')
    ch1 = ct.enhance(3.4)
    ch1.show(title='对比度3.4')
    

    在这里插入图片描述
    7. 调整图像的亮度
    PIL.ImageEnhance.Brightness(image) ,该方法主要用于调整图像的亮度,0.0的增强系数表示黑色图像。系数为1.0则得到原始图像。

    br = ImageEnhance.Brightness(org_img)
    be = br.enhance(0)
    be.show(title='亮度0')
    be = br.enhance(3)
    be.show(title='亮度3')
    

    在这里插入图片描述

    1. 调整图像的锐度
      PIL.ImageEnhance.Sharpness(image) ,该方法主要用于调整图像的锐度,0.0的增强因子为模糊图像,1.0的增强因子为原始图像,2.0的增强因子为锐化图像。
    sp = ImageEnhance.Sharpness(org_img)
    se = sp.enhance(0)
    se.show(title='锐度0')
    se1 = sp.enhance(20)
    se1.show(title='锐度20')
    

    在这里插入图片描述

    ImageFilter模块

    ImageFilter模块主要用于对图像进行过滤,增强边缘,模糊处理,该模块的使用方式是im.filter(ImageFilter)
    其中ImageFilter按照需求传入指定的过滤值。

    过滤值 作用
    ImageFilter.GaussianBlur 高斯模糊
    ImageFilter.BLUR 普通模糊
    ImageFilter.EDGE_ENHANCE 边缘增强
    ImageFilter.FIND_EDGES 找到边缘
    ImageFilter.EMBOSS 浮雕
    ImageFilter.CONTOUR 轮廓
    ImageFilter.SHARPEN 锐化

    下面一个个试下效果

    1. 原图
    from PIL import Image, ImageFilter
    im = Image.open('picture/img10.png')
    im.show()
    

    在这里插入图片描述
    2. 高斯模糊

    im1 = im.filter(ImageFilter.GaussianBlur)
    im1.show()
    

    在这里插入图片描述
    3. 普通模糊

    im2 = im.filter(ImageFilter.BLUR)
    im2.show()
    

    在这里插入图片描述
    4.边缘增强

    im3 = im.filter(ImageFilter.EDGE_ENHANCE)
    im3.show()
    

    在这里插入图片描述
    5. 找到边缘

    im4 = im.filter(ImageFilter.FIND_EDGES)
    im4.show()
    

    在这里插入图片描述
    6. 浮雕

    im5 = im.filter(ImageFilter.EMBOSS)
    im5.show()
    

    在这里插入图片描述
    7. 轮廓

    im6 = im.filter(ImageFilter.CONTOUR)
    im6.show()
    

    在这里插入图片描述
    8. 锐化

    im7 = im.filter(ImageFilter.SHARPEN)
    im7.show()
    

    在这里插入图片描述

    ImageGrab模块

    ImageGrab模块主要用于对屏幕进行截图,通过grab方法进行截取,如果不传入任何参数则表示全屏幕截图,否则是截取指定区域的图像。其中box格式是:(x1,x2,y1,y2)

    from PIL import ImageGrab
    im1 = ImageGrab.grab((0, 0, 600, 300))  # 截取屏幕600*300的区域的图像
    im2 = ImageGrab.grab()  # 不带参数表示全屏幕截图
    im1.show()
    im2.show()
    

    在这里插入图片描述

    利用Pillow库对图像增加水印

    利用Pillow库可以轻易的对图像增加水印
    首先,用PIL的Image函数读取图片
    接着,新建一张图(尺寸和原图一样)
    然后,在新建的图象上用PIL的ImageDraw把字给画上去,字的颜色从原图处获取。

    from PIL import Image, ImageDraw, ImageFont
    
    font_size = 8
    text = "泳池美女"
    
    img_raw = Image.open("../picture/beautiful.jpeg")
    # 1.读取图像,获取每一个像素值
    img_array = img_raw.load()
    # 2. 新建画布,选好要使用的字体大小
    new_img = Image.new('RGB', img_raw.size, 'gray')
    font = ImageFont.truetype("../picture/simsun.ttf", size=font_size)
    draw = ImageDraw.Draw(new_img)
    
    
    # 搞一个生成器(不断循环"泳池美女")
    def character_generate(text):
        while True:
            for i in range(len(text)):
                yield text[i]
    
    
    char_gen = character_generate(text)
    # 实现效果
    for y in range(0, img_raw.size[1], font_size):
        for x in range(0, img_raw.size[0], font_size):
            draw.text((x + 1, y + 1), next(char_gen), font=font, fill=img_array[x, y])
    
    new_img.convert('RGB').save("../picture/beautiful_result.jpeg")
    

    原图
    在这里插入图片描述
    添加文字后的效果图

    在这里插入图片描述

    总结

    本文详细介绍了Pillow库的使用,希望对读者朋友们有所帮助。

    参考

    Pillow官方文档

    源码获取

    需要获取源码的小伙伴可以关注下方的公众号,回复【python】

    我是码农飞哥,再次感谢您读完本文
    全网同名【码农飞哥】。不积跬步,无以至千里,享受分享的快乐
    我是码农飞哥,再次感谢您读完本文

  • 相关阅读:
    ios 数据类型转换 UIImage转换为NSData NSData转换为NSString
    iOS UI 12 block传值
    iOS UI 11 单例
    iOS UI 08 uitableview 自定义cell
    iOS UI 07 uitableviewi3
    iOS UI 07 uitableviewi2
    iOS UI 07 uitableview
    iOS UI 05 传值
    iOS UI 04 轨道和动画
    iOS UI 03 事件和手势
  • 原文地址:https://www.cnblogs.com/Fly-Bob/p/15422834.html
Copyright © 2011-2022 走看看