最全Pillow(PIL)入门教程(非常详细)_python pillow 教程,2024年最新Python面试送分题

简介: 最全Pillow(PIL)入门教程(非常详细)_python pillow 教程,2024年最新Python面试送分题

下面开始编写代码:

# 批量修改图片尺寸
import os
from PIL import Image
#读取图片目录
fileName = os.listdir('C:/Users/Administrator/Desktop/image01/')
print(fileName)
#设定尺寸
width = 350
height = 350
# 如果目录不存在,则创建目录
if not os.path.exists('C:/Users/Administrator/Desktop/NewImage/'):
    os.mkdir('C:/Users/Administrator/Desktop/NewImage/')
# 循环读取每一张图片
for img in fileName:
    old_pic = Image.open('C:/Users/Administrator/Desktop/image01/' + img)
    new_image = old_pic.resize((width, height),Image.BILINEAR)
    print (new_image)
    new_image.save('C:/Users/Administrator/Desktop/NewImage/'+img)

输出结果如下所示:

['向日葵.jpg', '国宝.jpg', '矩形图.jpg', '蝴蝶.jpg']
<PIL.Image.Image image mode=RGB size=350x350 at 0x2B9E670>
<PIL.Image.Image image mode=RGB size=350x350 at 0x31D0C90>
<PIL.Image.Image image mode=RGB size=350x350 at 0x2B90DB0>
<PIL.Image.Image image mode=RGB size=350x350 at 0x31D0C90>

NewImage 目录的内容如下:

图4:处理完成的图片

Pillow图像分离与合并

我们知道,图像(指数字图像)由许多像素点组成,像素是组成图像的基本单位,而每一个像素点又可以使用不同的颜色,最终呈现出了绚丽多彩的图像。在《Pillow Image对象属性》一节,我们介绍一些图片模式,它们的本质就是图片呈现颜色时需要遵循的规则,比如 RGB、RGBA、CYMK 等,而图像的分离与合并,指的就是图像颜色的分离和合并。

Image 类提供了用于分离图像和合并图像的方法 split() 和 merge() 方法,通常情况下,这两个方法会一起使用。

split()

split() 的使用方法比较简单,用来分离颜色通道。我们使用它来处理蝴蝶图片:

图1:pilow 图像处理操作

代码如下所示:

im=Image.open("C:/Users/Administrator/Desktop/1.jpg")
#修改图像大小,以适应图像处理
image=im.resize((450,400))
image.save("C:/Users/Administrator/Desktop/2.jpg")
#分离颜色通道,产生三个 Image对象
r,g,b = image.split()
r.show()
g.show()
b.show()

输出的结果,依次展示如下:

图2:分离结果预览

merge()

Image 类提供的 merge() 方法可以实现图像的合并操作。注意,图像合并,可以是单个图像合并,也可以合并两个以上的图像。

merge() 方法的语法格式如下:

Image.merge(mode, bands)

参数说明如下:

  • mode:指定输出图片的模式
  • bands:参数类型为元组或者列表序列,其元素值是组成图像的颜色通道,比如 RGB 分别代表三种颜色通道,可以表示为 (r,g,b)。

注意,该函数会返回一个新的 Image 对象。

下面对图像合并的两种类型分别进行介绍:

一. 单个图像的合并指的是将颜色通道进行重新组合,从而得到不一样的图片效果,代码如下所示:

from PIL import Image
im=Image.open("C:/Users/Administrator/Desktop/1.jpg")
#修改图像大小,以适应图像处理
image=im.resize((450,400))
image.save("C:/Users/Administrator/Desktop/2.jpg")
#分离颜色通道,产生三个 Image对象
r,g,b = image.split()
#重新组合颜色通道,返回先的Image对象
image_merge=Image.merge('RGB',(b,g,r))
image_merge.show()
#保存图像至桌面
image_merge.save("C:/Users/Administrator/Desktop/3.jpg")

新合成的图像入如下所示:

图3:图像合并操作

两张图片的合并操作也并不复杂,但是要求两张图片的模式、图像大小必须要保持一致,否则不能合并。因此,对于那些模式、大小不同的图片要进行预处理。

下面我们将蝴蝶图与向日葵图进行合并,向日葵原图如下:

图4:向日葵原图

示例代码如下:

from PIL import Image
#打开图2.jpg
im_1 = Image.open("C:/Users/Administrator/Desktop/2.jpg")
im_2= Image.open("C:/Users/Administrator/Desktop/向日葵.jpg")
#因为两种图片的图片格式一致,所以仅需要处理图片的大小,让它们保持一致
#让 im_2 的图像尺寸与 im_1 一致,注意此处新生成了 Image 对象
image = im_2.resize(im_1.size)
#接下来,对图像进行颜色分离操作
r1, g1 ,b1 = im_1.split()
r2, g2 , b2 = image.split()
# 合并图像
im_3 = Image.merge('RGB',[r2,g1,b2])
im_3.show()
im_3.save("C:/Users/Administrator/Desktop/合成.jpg")

预览图像的合成结果:

图5:合成图像

扩展知识:blend() 混合图片

Image 类也提供了 blend() 方法来混合 RGBA 模式的图片(PNG 格式),函数的语法格式如下:

Image.blend(image1,image2, alpha)

参数说明如下:

  • image1,image2:表示两个 Image 对象。
  • alpha:表示透明度,取值范围为 0 到 1,当取值为 0 时,输出图像相当于 image1 的拷贝,而取值为 1 时,则是 image2 的拷贝,只有当取值为 0.5 时,才为两个图像的中合。因此改值的大小决定了两个图像的混合程度。

与 RGB 模式相比,RGBA 在 RGB 的基础上增加了透明度,通过 Alpha 取值来决定两个图像的混合程度。示例如下:

""""
混合 rgba模式的图像
"""
im1 = Image.open("C:/Users/Administrator/Desktop/c-net.png")
image = Image.open("C:/Users/Administrator/Desktop/心形函数图像.png")
im2=image.resize(im1.size)
def blend_im(im1,im2):
     #设置 alpha 为 0.5
    Image.blend(im1,im2,0.5).save("C:/Users/Administrator/Desktop/C语言中文网.png")
#调用函数
blend_im(im1,im2)  

输出结果如下:

图6:混合图像

Pillow图像裁剪、复制、粘贴操作

图像的剪裁、复制、粘贴是图像处理过程中经常使用的基本操作,Pillow Image 类提供了简单、易用的 API 接口,能够帮助您快速实现这些简单的图像处理操作。

图像裁剪操作

Image 类提供的 crop() 函数允许我们以矩形区域的方式对原图像进行裁剪,函数的语法格式如下:

crop(box=None)

box:表示裁剪区域,默认为 None,表示拷贝原图像。

注意:box 是一个有四个数字的元组参数 (x_左上,y_左下,x1_右上,y1_右下),分别表示被裁剪矩形区域的左上角 x、y 坐标和右下角 x,y 坐标。默认 (0,0) 表示坐标原点,宽度的方向为 x 轴,高度的方向为 y 轴,每个像素点代表一个单位。

crop() 函数的会返回一个 Image 对象,使用示例如下:

"""
裁剪图像
"""
im = Image.open("C:/Users/Administrator/Desktop/C语言中文网.png")
box =(0,0,200,100)
im_crop = im.crop(box)
im_crop.show()

输出图像显示如下:

图1:图像裁剪

最终,在原图的基础上裁剪出一张像素为 200 * 100 的图像。

图像拷贝和粘贴

拷贝、粘贴操作几乎是成对出现的,Image 类提供了 copy() 和 paste() 方法来实现图像的复制和粘贴。其中复制操作(即 copy() 方法)比较简单,下面主要介绍 paste() 粘贴方法,语法格式如下所示:

paste(image, box=None, mask=None)

该函数的作用是将一张图片粘贴至另一张图片中。注意,粘贴后的图片模式将自动保持一致,不需要进行额外的转换。参数说明如下:

  • image:指被粘贴的图片;
  • box:指定图片被粘贴的位置或者区域,其参数值是长度为 2 或者 4 的元组序列,长度为 2 时,表示具体的某一点 (x,y);长度为 4 则表示图片粘贴的区域,此时区域的大小必须要和被粘贴的图像大小保持一致。
  • mask:可选参数,为图片添加蒙版效果。

下面复制一张原图像的副本,对副本进行裁剪、粘贴操作,代码如下所示:

im = Image.open("C:/Users/Administrator/Desktop/C语言中文网.png")
#复制一张图片副本
im_copy=im.copy()
#对副本进行裁剪
im_crop = im_copy.crop((0,0,200,100))
#创建一个新的图像作为蒙版,L模式,单颜色值
image_new = Image.new('L', (200, 100), 200)
#将裁剪后的副本粘贴至副本图像上,并添加蒙版
im_copy.paste(im_crop,(100,100,300,200),mask=image_new)
#显示粘贴后的图像
im_copy.show()

输出的显示结果,如下所示:

图2:图像复制粘贴

Pillow图像几何变换

图像的几何变换主要包括图像翻转、图像旋转和图像变换操作,Image 类提供了处理这些操作的函数 transpose()、rotate() 和 transform(),下面分别对它们进行讲解。

transpose()翻转操作

该函数可以实现图像的垂直、水平翻转,语法格式如下:

Image.transpose(method)

method 参数决定了图片要如何翻转,参数值如下:

  • Image.FLIP_LEFT_RIGHT:左右水平翻转;
  • Image.FLIP_TOP_BOTTOM:上下垂直翻转;
  • Image.ROTATE_90:图像旋转 90 度;
  • Image.ROTATE_180:图像旋转 180 度;
  • Image.ROTATE_270:图像旋转 270 度;
  • Image.TRANSPOSE:图像转置;
  • Image.TRANSVERSE:图像横向翻转。

使用示例如下:

im = Image.open("C:/Users/Administrator/Desktop/c-net.png")
#返回一个新的Image对象
im_out=im.transpose(Image.FLIP_LEFT_RIGHT)
im_out.show()
im_out.save("C:/Users/Administrator/Desktop/水平翻转.png")

图像显示结果,如下所示:

图1:图像翻转操作

rotate()任意角度旋转

当我们想把图像旋转任意角度时,可以使用 rotate() 函数,语法格式如下:

Image.rotate(angle, resample=PIL.Image.NEAREST, expand=None, center=None, translate=None, fillcolor=None)

参数说明如下:

  • angle:表示任意旋转的角度;
  • resample:重采样滤波器,默认为 PIL.Image.NEAREST 最近邻插值方法;
  • expand:可选参数,表示是否对图像进行扩展,如果参数值为 True 则扩大输出图像,如果为 False 或者省略,则表示按原图像大小输出;
  • center:可选参数,指定旋转中心,参数值是长度为 2 的元组,默认以图像中心进行旋转;
  • translate:参数值为二元组,表示对旋转后的图像进行平移,以左上角为原点;
  • fillcolor:可选参数,填充颜色,图像旋转后,对图像之外的区域进行填充。

使用示例如下:

im = Image.open("C:/Users/Administrator/Desktop/c-net.png")
#translate的参数值可以为负数,并将旋转图之外的区域填充为绿色
#返回同一个新的Image对象
im_out=im.rotate(45,translate=(0,-25),fillcolor="green")
im_out.show()
im_out.save("C:/Users/Administrator/Desktop/旋转图像.png")

输出结果:

图2:图像旋转

transform()图像变换

该函数能够对图像进行变换操作,通过指定的变换方式,产生一张规定大小的新图像,语法格式如下:

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

参数说明:

  • size:指定新图片的大小;
  • method:指定图片的变化方式,比如 Image.EXTENT 表示矩形变换;
  • data:该参数用来给变换方式提供所需数据;
  • resample:图像重采样滤波器,默认参数值为 PIL.Image.NEAREST。

使用示例如下:

from PIL import Image
im = Image.open("C:/Users/Administrator/Desktop/c-net.png")
#设置图像大小250*250,并根据data的数据截取原图像的区域,生成新的图像
im_out=im.transform((250,250),Image.EXTENT,data=[0,0,30 + im.width//4,im.height//3])
im_out.show()
im_out.save("C:/Users/Administrator/Desktop/变换.png")

输出图像显示如下:

图3:图像矩形变换

Pillow图像降噪处理

由于成像设备、传输媒介等因素的影响,图像总会或多或少的存在一些不必要的干扰信息,我们将这些干扰信息统称为“噪声”,比如数字图像中常见的“椒盐噪声”,指的是图像会随机出现的一些白、黑色的像素点。图像噪声既影响了图像的质量,又妨碍人们的视觉观赏。因此,噪声处理是图像处理过程中必不可少的环节之一,我们把处理图像噪声的过程称为“图像降噪”。

随着数字图像技术的不断发展,图像降噪方法也日趋成熟,通过某些算法来构造滤波器是图像降噪的主要方式。滤波器能够有效抑制噪声的产生,并且不影响被处理图像的形状、大小以及原有的拓扑结构。

Pillow 通过 ImageFilter 类达到图像降噪的目的,该类中集成了不同种类的滤波器,通过调用它们从而实现图像的平滑、锐化、边界增强等图像降噪操作。常见的降噪滤波器如下表所示:

名称 说明
ImageFilter.BLUR 模糊滤波,即均值滤波
ImageFilter.CONTOUR 轮廓滤波,寻找图像轮廓信息
ImageFilter.DETAIL 细节滤波,使得图像显示更加精细
ImageFilter.FIND_EDGES 寻找边界滤波(找寻图像的边界信息)
ImageFilter.EMBOSS 浮雕滤波,以浮雕图的形式显示图像
ImageFilter.EDGE_ENHANCE 边界增强滤波
ImageFilter.EDGE_ENHANCE_MORE 深度边缘增强滤波
ImageFilter.SMOOTH 平滑滤波
ImageFilter.SMOOTH_MORE 深度平滑滤波
ImageFilter.SHARPEN 锐化滤波
ImageFilter.GaussianBlur() 高斯模糊
ImageFilter.UnsharpMask() 反锐化掩码滤波
ImageFilter.Kernel() 卷积核滤波
ImageFilter.MinFilter(size) 最小值滤波器,从 size 参数指定的区域中选择最小像素值,然后将其存储至输出图像中。
ImageFilter.MedianFilter(size) 中值滤波器,从 size 参数指定的区域中选择中值像素值,然后将其存储至输出图像中。
ImageFilter.MaxFilter(size) 最大值滤波器
ImageFilter.ModeFilter() 模式滤波

从上述表格中选取几个方法进行示例演示,下面是等待处理的原始图像:

图1:pilow图像处理

模糊处理

# 导入Image类和ImageFilter类
from PIL import Image,ImageFilter
im = Image.open("C:/Users/Administrator/Desktop/国宝.jpg")
#图像模糊处理
im_blur=im.filter(ImageFilter.BLUR)
im_blur.show()
im_blur.save("C:/Users/Administrator/Desktop/模糊.png")

输出图像如下:

图2:图像模糊

轮廓图

from PIL import Image,ImageFilter
im = Image.open("C:/Users/Administrator/Desktop/国宝.jpg")
#生成轮廓图
im2=im.filter(ImageFilter.CONTOUR)
im2.show()
im2.save("C:/Users/Administrator/Desktop/轮廓图.png")

输出图像,显示如下:

图3:图像轮廓图

边缘检测

from PIL import Image,ImageFilter
im = Image.open("C:/Users/Administrator/Desktop/国宝.jpg")
#边缘检测
im3=im.filter(ImageFilter.FIND_EDGES)
im3.show()
im3.save("C:/Users/Administrator/Desktop/边缘检测.png")

输出图像结果:

图4:图像边缘检测

浮雕图

from PIL import Image,ImageFilter
im = Image.open("C:/Users/Administrator/Desktop/国宝.jpg")
#浮雕图
im4=im.filter(ImageFilter.EMBOSS)
im4.show()
im4.save("C:/Users/Administrator/Desktop/浮雕图.png")

输出图像如下:

图5:浮雕图

平滑图像

#生成平滑图像
from PIL import Image,ImageFilter
im = Image.open("C:/Users/Administrator/Desktop/国宝.jpg")
#平滑图smooth
im5=im.filter(ImageFilter.SMOOTH)
im5.show()
im5.save("C:/Users/Administrator/Desktop/平滑图.png")

输出图像如下:

图6:平滑图

如果您使用过 PhotoShop(简称 Ps,一款专业的图像处理软件)、Fireworks(简称 Fw,一款专业的图像处理软件) 或者手机美图软件的话,其实不难发现,上述操作就是给图片添加一个“滤镜”,通过添加滤镜来改变图片的外观,从而影响了我们对于图片的感官体验。

Pillow图像颜色处理

Pillow 提供了颜色处理模块 ImageColor,该模块支持不同格式的颜色,比如 RGB 格式的颜色三元组、十六进制的颜色名称(#ff0000)以及颜色英文单词(“red”)。同时,它还可以将 CSS(层叠样式表,用来修饰网页)风格的颜色转换为 RGB 格式。

注意,在 ImageColor 模块对颜色的大小并不敏感,比如 “Red” 也可以写为 " red"。

颜色命名

ImageColor 支持多种颜色模式的的命名(即使用固定的格式对颜值进行表示),比如我们熟知的 RGB 色彩模式,除此之外,还有 HSL (色调-饱和度-明度)、HSB (又称 HSV,色调-饱和度-亮度)色彩模式。下面对 HSL 做简单介绍:

  • H:即 Hue 色调,取值范围 0 -360,其中 0 表示“red”,120 表示 “green”,240 表示“blue”;
  • S:即 Saturation 饱和度,代表色彩的纯度,取值 0~100%,其中 0 代表灰色(gry),100% 表示色光最饱和;
  • L:即 Lightness 明度,取值为 0~100%,其中 0 表示“black”黑色,50% 表示正常颜色,100% 则表示白色。

下面使用 HSL 色彩模式表示红色,格式如下:

HSL(0,100%,50%)

此时的颜色为“纯红色”,等同于 RGB (255,0,0)。如果想了解有关 HSL/HSB 的更多知识,点击链接前往。

ImageColor 模块比较简单,只提供了两个常用方法,分别是 getrgb() 和 getcolor() 函数。

getrgb()方法

顾名思义,该函数用来得到颜色的 RGB 值,语法格式如下:

PIL.ImageColor.getrgb(color)

使用示例如下:

from PIL import Image,ImageColor
# getrgb()方法
color1=ImageColor.getrgb("blue")
print(color1)
color2=ImageColor.getrgb('#DCDCDC')
print(color2)
#使用HSL模式红色
color3=ImageColor.getrgb('HSL(0,100%,50%)')
print(color3)

输出结果如下:

(0, 0, 255)
(220, 220, 220)
(255, 0, 0)

通过 new() 方法可以新建图像,此时也可以使用 ImageColor.getrgb(),如下所示:

#使用new()绘制新的图像
im= Image.new("RGB", (200, 200), ImageColor.getrgb("#EEB4B4"))
im.save("C:/Users/Administrator/Desktop/xin.jpg")

显示图片如下:

图1:新建图像

getcolor()

该方法与 getrgb() 类似,同样用来获取颜色值,不过它多了一个mode参数,因此该函数可以获取指定色彩模式的颜色值。语法格式如下:

PIL.ImageColor.getcolor(color, mode)

参数说明如下:

  • color:一个颜色名称,字符串格式,可以是颜色的英文单词,或者十六进制颜色名。如果是不支持的颜色,会报 ValueError 错误;
  • mode:指定色彩模式,如果是不支持的模式,会报 KeyError 错误。

使用示例如下:

color4=ImageColor.getcolor('#EEA9B8','L')
print(color4)
color5=ImageColor.getcolor('yellow','RGBA')
print(color5)

输出结果:

191
(255, 255, 0, 255)

Pillow为图片添加水印

为图片添加水印能够在一定程度上避免其他人滥用您的图片,这是保护图片版权的一种有效方式。因此,当您在微博、或者博客等一些公众平台分享图片的时候,建议您为自己的图片添加一个水印,来证明这张图片属于您。

添加水印的方式的有很多种,比如通过一些图像处理软件,或者手机美图软件都可以实现添加水印的操作,但是这种操作比较复杂,甚至有些软件还不是免费的。

Pillow 库提供了添加水印的方法,操作简单,易学、易用。下面我们讲解如何使用 PIilow 给图片添加水印。

我们知道,水印是附着在原图片上一段文字信息,因此添加水印的过程中会涉及两个问题:

  • 第一、如何使文字信息附着在图片上;
  • 第二、如何绘制文字信息。

只要解决了这两个问题就可以成功添加水印。Pillow 提供的ImageDrawImageFont模块成功解决了上述问题。

ImageDraw

PIL.ImageDraw 模块提供了一系列的绘图方法,通过该模块可以创建一个新的图形,或者在现有的图像上再绘制一个图形,从而起到对原图注释和修饰的作用。

下面创建一个 ImageDraw 对象,并对该对象的使用方法做简单介绍:

draw = ImageDraw.Draw(im)

上述方法会返回一个 ImageDraw 对象,参数 im 表示 Image 对象。这里我们可以把 Image 对象理解成画布,通过调用 ImageDraw 对象的一些方法,实现了在画布上绘制出新的图形目的。ImageDraw 对象的常用方法如下表所示:

方法 说明
text 在图像上绘制文字
line 绘制直线、线段
eclipse 绘制椭圆形
rectangle 绘制矩形
polygon 绘制多边形

表格中第一个方法 text() 需要与 ImageFont 模块一起使用,在下面会做详细介绍。

绘制矩形图的语法格式如下:

draw.rectangle(xy, fill=None, outline=None)

参数说明如下:

  • xy:元组参数值,以图像的左上角为坐标原点,表示矩形图的位置、图形大小的坐标序列,形如 ((x1,y1,x2,y2));
  • fill:矩形图的背景填充色;
  • outline:矩形图的边框线条颜色。

下面看一组简单的示例:

from PIL import Image,ImageDraw
#创建 Image 对象,当做背景图
im = Image.new('RGB',(200,200),color='gray')
#创建 ImageDraw 对象
draw = ImageDraw.Draw(im)
#以左上角为原点,绘制矩形。元组坐标序列表示矩形的位置、大小;fill设置填充色为红色,outline设置边框线为黑色
draw.rectangle((50,100,100,150),fill=(255,0,0),outline=(0,0,0))
#查看原图片
im.show()
#保存图片
im.save("C:/Users/Administrator/Desktop/添加矩形图.png")

图形显示结果如下:

图1:绘制红色矩形

ImageFont

PIL.ImagreFont 模块通过加载不同格式的字体文件,从而在图像上绘制出不同类型的文字,比如 TrueType 和 OpenType 类型的字体。

创建字体对象的语法格式如下:

font = ImageFont.truetype(font='字体文件路径', size=字体大小)

如果想要在图片上添加文本,还需要使用 ImageDraw.text() 方法,语法格式如下:

d.text((x,y), "text", font, fill)

参数说明如下:

  • (x,y):图像左上角为坐标原点,(x,y) 表示添加文本的起始坐标位置;
  • text:字符串格式,要添加的文本内容;
  • font:ImageFont 对象;
  • fill:文本填充颜色。

下面看一组使用示例,如下所示:

from PIL import Image,ImageFont,ImageDraw
#打开图片,返回 Image对象
im = Image.open("C:/Users/Administrator/Desktop/c-net.png")
#创建画布对象
draw = ImageDraw.Draw(im)
#加载计算机本地字体文件
font=ImageFont.truetype('C:/Windows/Fonts/msyh.ttc',size=36)
#在原图像上添加文本
draw.text(xy=(80,50),text='C语言中文网',fill=(255,0,0),font=font)
im.show()
im.save("C:/Users/Administrator/Desktop/c.png")

图像显示结果如下:

图2:添加文本

添加图片水印

通过上述知识的学习,我们对ImageDrawImageFont模块有了大体的认识,并且也解决了如何给图片添加水印的两个关键问题。以下示例展示了为图片添加水印的详细过程,代码如下所示:

"""
添加水印(函数式编程)
"""
from PIL import Image,ImageFont,ImageDraw
font=ImageFont.truetype('C:/Windows/Fonts/msyh.ttc',size=30)
def creating\_watermark(im,text,font=font):
    #给水印添加透明度,因此需要转换图片的格式
    im_rgba=im.convert('RGBA')
    im_text_canvas=Image.new('RGBA',im_rgba.size,(255,255,255,0))
    print(im_rgba.size[0])
    draw = ImageDraw.Draw(im_text_canvas)
    #设置文本文字大小
    text_x_width,text_y_height = draw.textsize(text,font=font)
    print(text_x_width,text_y_height)
    text_xy = (im_rgba.size[0] - text_x_width, im_rgba.size[1] - text_y_height)
    print(text_xy)
    #设置文本颜色(绿色)和透明度(半透明)
    draw.text(text_xy,text,font=font,fill=(255,255,255,128))
    #将原图片与文字复合
    im_text=Image.alpha_composite(im_rgba,im_text_canvas)
    return  im_text
image = Image.open("C:/Users/Administrator/Desktop/c-net.png")
image.show()
image_water = creating_watermark(image,'@c语言中文网')
image_water.show()
image_water.save("C:/Users/Administrator/Desktop/c语言中文网.png")

添加水印后的效果图:

图3:添加水印后效果

Pillow和ndarray数组

NumPy 是 Python 科学计算的基础数据包,它被大量的应用于机器学习领域,比如图像识别、自然语言处理、数据挖掘等。想了解学习 NumPy,可跳转至《NumPy快速入门教程》。

ndarray 是 NumPy 中的数组类型,也称为 ndarray 数组,该数组可以与 Pillow 的 PIL.Image 对象实现相互转化。

ndarray数组创建图像

下面通过 ndarray 数组构建一个 Image 对象,并将图像显示出来。示例如下:

#导入相关的包
from PIL import Image
#使用numpy之前需要提前安装
import numpy as np
#创建 300\*400的图像,3个颜色通道
array = np.zeros([300,400,3],dtype=np.uint8)
#rgb色彩模式
array[:,:200]=[255,0,0]
array[:,200:]=[255,255,0]
img = Image.fromarray(array)
img.show()
img.save("C:/Users/Administrator/Desktop/数组生成图像.png")

输出结果如下所示:

图1:NumPy数组创建图像

图像转化为ndarray数组

下面将图像以 ndarray 数组的形式进行输出,示例如下:

from PIL import Image
import numpy as np
img = Image.open("C:/Users/Administrator/Desktop/大熊猫.png")
img.show()
#Image图像转换为ndarray数组
img_2 = np.array(img)
print(img_2)
#ndarray转换为Image图像
arr_img = Image.fromarray(img_2)
#显示图片
arr_img.show()
#保存图片
arr_img.save("C:/Users/Administrator/Desktop/arr\_img.png")

图片展示结果:

图2:显示原图

组成图片的像素点数组如下所示:

[[[113 108 105]
  [118 113 110]
  [139 131 128]
  ...
  [139 148 155]
  [137 146 153]
  [139 148 155]]
[[ 97  92  89]
  [124 118 115]
  [137 129 126]
  ...
  [143 152 159]
  [140 149 156]
  [140 149 156]]
[[102  97  94]
  [123 118 115]
  [135 128 125]
  ...
  [144 153 160]
  [142 151 158]
  [143 152 159]]
...
[[168 175 134]
  [175 183 142]
  [151 162 120]
  ...
  [ 99 143  66]
  [111 155  77]
  [131 175  98]]
[[152 164 118]
  [147 160 114]
  [140 156 109]
  ...
  [123 167  87]
  [126 171  90]
  [120 165  84]]
[[136 154 104]
  [127 145  95]
  [156 176 125]
  ...
  [168 213 130]
  [142 187 104]
  [ 69 114  31]]]

Pillow生成GIF动态图

GIF(Graphics Interchange Format,图形交换格式)是一种“位图”图像格式,它以.gif作为图像的扩展名。GIF 图片非常适合在互联网中使用,这是因为它采用了图像预压缩技术,该技术的应用,在一定程度上减少了图像传播、加载所消耗的时间。

与其他格式的图片相比,GIF 还有一项非常重要的应用,那就是生成动态图。我们知道,Pillow 能够处理多种图像格式,包括 GIF 格式,它可以将静态格式图片(png、jpg)合成为 GIF 动态图。

注意:Pillow 总是以灰度模式(L)或调色板模式(P)来读取 GIF 文件。

下面看一组示例:如何使用 Pillow 生成 GiF 动态图。(示例中所用图片素材,点击链接下载,提取码:n1v2)

import os
import random
from PIL import Image
def png_to_gif(png_path,gif_name):
    """png合成gif图像"""
    frames = []
    # 返回文件夹内的所有静态图的列表
    png_files = os.listdir(png_path)
    # 打印返回的列表
    print(png_files)
    # 读取文件内的静态图
    for frame_id in range(1,len(png_files)+1):
        frame = Image.open(os.path.join(png_path,'image%d.png'%frame_id))
        frames.append(frame)
    # 以第一张图片作为开始,将后续5张图片合并成 gif 动态图
    # 参数说明:
    # save_all 保存图像;transparency 设置透明背景色;duration 单位毫秒,动画持续时间, 
    # loop=0 无限循环;disposal=2 恢复原背景颜色。参数详细说明,请参阅官方文档,网址见文章末尾处。
    frames[0].save(gif_name,save_all=True,append_images=frames[1:],transparency=0,duration=2000,loop=0,disposal=2)
#调用函数,传入对应的参数
png_to_gif("C:/Users/Administrator/Desktop/image",'C:/Users/Administrator/Desktop/t.gif')

动态效果图,如下所示:

想要了解关于 Pillow 的更多的知识,请参考官方文档:点击前往

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、学习软件

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

三、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。


相关文章
|
7天前
|
Python
SciPy 教程 之 Scipy 显著性检验 3
本教程介绍Scipy显著性检验,包括其基本概念、原理及应用。显著性检验用于判断样本与总体假设间的差异是否显著,是统计学中的重要工具。Scipy通过`scipy.stats`模块提供了相关功能,支持双边检验等方法。
13 1
|
9天前
|
机器学习/深度学习 Python
SciPy 教程 之 SciPy 插值 2
SciPy插值教程:介绍插值概念及其在数值分析中的应用,特别是在处理数据缺失时的插补和平滑数据集。SciPy的`scipy.interpolate`模块提供了强大的插值功能,如一维插值和样条插值。通过`UnivariateSpline()`函数,可以轻松实现单变量插值,示例代码展示了如何对非线性点进行插值计算。
11 3
|
12天前
|
机器学习/深度学习 数据处理 Python
SciPy 教程 之 SciPy 空间数据 4
本教程介绍了SciPy的空间数据处理功能,主要通过scipy.spatial模块实现。内容涵盖空间数据的基本概念、距离矩阵的定义及其在生物信息学中的应用,以及如何计算欧几里得距离。示例代码展示了如何使用SciPy计算两点间的欧几里得距离。
27 5
|
11天前
|
机器学习/深度学习 Python
SciPy 教程 之 SciPy 空间数据 6
本教程介绍了SciPy处理空间数据的方法,包括使用scipy.spatial模块进行点位置判断、最近点计算等内容。还详细讲解了距离矩阵的概念及其应用,如在生物信息学中表示蛋白质结构等。最后,通过实例演示了如何计算两点间的余弦距离。
21 3
|
10天前
|
机器学习/深度学习 数据处理 Python
SciPy 教程 之 SciPy 空间数据 7
本教程介绍了SciPy的空间数据处理功能,涵盖如何使用`scipy.spatial`模块进行点的位置判断、最近点计算等操作。还详细解释了距离矩阵的概念及其在生物信息学中的应用,以及汉明距离的定义和计算方法。示例代码展示了如何计算两个点之间的汉明距离。
17 1
|
7天前
|
机器学习/深度学习 数据处理 Python
SciPy 教程 之 SciPy 插值 3
本教程介绍了SciPy中的插值方法,包括什么是插值及其在数据处理和机器学习中的应用。通过 `scipy.interpolate` 模块,特别是 `Rbf()` 函数,展示了如何实现径向基函数插值,以平滑数据集中的离散点。示例代码演示了如何使用 `Rbf()` 函数进行插值计算。
14 0
|
7天前
|
Python
SciPy 教程 之 Scipy 显著性检验 1
本教程介绍Scipy显著性检验,包括统计假设、零假设和备择假设等概念,以及如何使用scipy.stats模块进行显著性检验,以判断样本与总体假设间是否存在显著差异。
12 0
|
3月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
11天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
13天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
38 4