PIL库参考文档之Image模块

原文:

https://pillow-cn.readthedocs.io/zh_CN/latest/reference/Image.html

中文版参考文档不全,所以自己试着翻译了一下,以下~备注部分,测试程序为自己添加~

PIL安装

下载地址:https://pypi.org/simple/pillow/

找到对应自己Python版本的安装包,比方我的Python版本是3.7,64位的,就下载了Pillow-6.1.0-cp37-cp37m-win_amd64.whl

Image模块

Image模块提供一个同名的类用来表示一张PIL图像,该模块也提供很多工厂函数,用来从文件中载入图片或者创建新图片。

例子

以下脚本载入一张图片,旋转45度,将其显示在外部预览窗口上(通常Unix系统使用XV......Windows系统使用画图程序)

打开,旋转,用默认图片浏览器显示一张图片

from PIL import Image

im = Image.open("bride.jpg")im.rotate(45).show()

备注(im.rotate()传入正值逆时针旋转,传入负值顺时针旋转

以下脚本为当前目录所有jpeg图片创建完美的128x128尺寸缩略图

创建缩略图

from PIL import Image

import glob,os

size=(128,128)

for infile in glob.glob("*.jpg"):

    (file,ext)=os.path.splitext(infile)

    im=Image.open(infile)

    im.thumbnail(size,Image.ANTIALIAS)

im.save(file+".thumbnail.jpeg","JPEG")

备注

  1. globpython自带库,glob.glob("*.jpg")返回当前文件夹下所有jpg文件名,不包含路径
  2. os.path.spiltext(file),将比如xxx.jpg字符串分割为xxx.jpg并返回分割结果
  3. 运行该程序应该事先在当下目录放一些jpg格式图片文件

函数

PIL.Image.open(fpmode='r')

打开给定的图片文件,并返回文件标识

这是一个延时操作,该函数取得文件标识之后,文件保持被打开状态。并且在你处理数据之前,该函数不会去读取文件中的数据。

参数:

·file——一个文件名字符串或者一个文件对象。如果是文件对象,必须执行read(),seek()tell()方法,并且用二进制模式打开

·mode——打开模式,如果给定,参数必须是”r”

返回:一个Image objet

引发IOError:如果文件不存在,或者文件无法识别

备注:当使用Image.open("C:\Users\Administrator\Desktop\1.jpg")打开一张图片时,可能会报错

nunicodeessscape codec can't decode bytes in xxx:truncated\UXXXXXXXX escape,改成Image.open(r"C:\Users\Administrator\Desktop\1.jpg")就好了

图片处理

PIL.Image.alpha_composite(im1im2)

图像通道融合,m2复合在m1(原文Alpha composite im2 over im1)

参数:

·im1,第一张图片

·im2,第二章图片,必须和第一张图片具有相同的模式(备注,貌似只能都是RGBA格式),尺寸

返回:一个图片对象

测试程序:

from PIL import Image

img1=Image.open(r"C:\Users\Administrator\Desktop\1.jpg").convert(mode="RGBA")

img2=Image.open(r"C:\Users\Administrator\Desktop\1.jpg").convert(mode="RGBA")

newImg=Image.alpha_composite(img1,img2)

newImg.show()

这个貌似没什么效果,这个函数只能融合两个大小一样的RGBA格式图片,所以这里用了convert(mode="RGBA")

转化成RGBA格式,否则就会报错

PIL.Image.blend(im1im2alpha)

使用一个alpha常量,融合两张输入的图片,产生一张新图片

计算方法:

out = image1 * (1.0 - alpha) + image2 * alpha

参数

·im1——第一张图片

·im2——第二张图片,与第一张图片具有相同的模式和尺寸

·alpha——插入的alpha因子,如果值为0.0,返回第一张图片的拷贝,如果值为1.0,返回第二章图片的拷贝,对于alpha的值没有限制...

返回:一个图片对象

测试程序:

from PIL import Image

img1=Image.open(r"C:\Users\Administrator\Desktop\1.jpg").convert(mode="RGBA")

img2=Image.new("RGBA",img1.size,"red")

 

newImg=Image.blend(img1,img2,0.5)

newImg.show()

这个程序是蛮有意思的,会在第一张图片上加上一层红色遮罩

参考:https://www.cnblogs.com/Lival/p/6211602.html

PIL.Image.composite(image1image2mask)

通过在融合图像的基础上,加入一个具有透明度的遮罩来创建一张复合图(原文:Create composite image by blending images using a transparency mask

参数

·image1——第一张图片

·image2——第二张图片,与第一张图片具有相同模式和尺寸

·mask——一张mask图片,这张图片可以是 “1”, “L”, or “RGBA”模式的,且必须与前两张图片具有相同的尺寸

测试程序

from PIL import Image

 

img1=Image.open(r"C:\Users\Administrator\Desktop\1.jpg")

img2=Image.open(r"C:\Users\Administrator\Desktop\2.jpg")

(r,g,b)=img2.split()

newImg=Image.composite(img1,img2,b)

newImg.show()

这个程序选择图片比较重要,不然就没有效果,第一章图片为背景为白色效果比较明显点

参考:https://blog.csdn.net/MiniCatTwo/article/details/80566129

PIL.Image.eval(image*args)

使用函数操作图片的每一个像素位(该函数应该带有一个参数)

参数,如果图片有多个波段,那么函数将应用于图片的每个波段。该函数对每个像素位只计算一次,所以不能使用随机数或者其他生成器。

·image——输入图片

·function——一个函数对象,带一个整型参数

测试程序

from PIL import Image

img1=Image.open(r"C:\Users\Administrator\Desktop\1.jpg")

newImg=Image.eval(img1,lambda x:x*6)

newImg.show()

截止现在,我对于像素位操作所产生的结果不清楚,所以函数就只好随便写

PIL.Image.merge(modebands)

将一组单波段图片合并到一个多波段图片中

参数

·mode——输出图片的模式

·bands——单波段图片的序列,序列中所有波段必须有相同尺寸

测试程序

from PIL import Image

img1=Image.open(r"C:\Users\Administrator\Desktop\1.jpg")

img2=Image.open(r"C:\Users\Administrator\Desktop\2.jpg")

(r1,g1,b1)=img1.split()

(r2,g2,b2)=img2.split()

temp=[r1,g2,b1]

newImg=Image.merge("RGB",temp)

newImg.show()

参考:https://blog.csdn.net/minicattwo/article/details/80572152

构造图片

PIL.Image.new(modesizecolor=0)

创新一张新图,用给定的模式和尺寸

参数

·mode——新图使用的模式

·size——一个包含两个值的元组,设置图片宽高

·color——设置图片颜色,默认是黑色。当给定值,如果是单个整型或者浮点型数值,表示创建单一波段图片;如果是一个元组则表示创建多波段的图片(元组的一个值创建一个波段)。当创建RGB图片的时候,你还可以使用ImageColor模块支持的颜色。如果颜色值为空,则图片不将初始化。

返回:一个图片对象

测试代码

from PIL import Image

 

#new1=Image.new("L",(400,400),"red")

#new1=Image.new("P",(400,400),20)

new1=Image.new("P",(400,400),(63,136,191))

new1.show()

关于图片模式

The mode of an image defines the type and depth of a pixel in the image. The current release supports the following standard modes:

1 (1-bit pixels, black and white, stored with one pixel per byte)

L (8-bit pixels, black and white)

P (8-bit pixels, mapped to any other mode using a color palette)

RGB (3x8-bit pixels, true color)

RGBA (4x8-bit pixels, true color with transparency mask)

CMYK (4x8-bit pixels, color separation)

YCbCr (3x8-bit pixels, color video format)

Note that this refers to the JPEG, and not the ITU-R BT.2020, standard

LAB (3x8-bit pixels, the L*a*b color space)

HSV (3x8-bit pixels, Hue, Saturation, Value color space)

I (32-bit signed integer pixels)

F (32-bit floating point pixels)

1表示,1比特像素(大概一个像素一位就可以表示出来?因为要么黑要么白色),黑白两色,每个字节存储一个像素...

测试一下,把彩色图片编程黑白色:

from PIL import Image

img1=Image.open(r"C:\Users\Administrator\Desktop\mylove.jpg").convert(mode="L")

img1.show()

关于图片模式转换可以参考:

https://blog.csdn.net/icamera0/article/details/50843172

https://blog.csdn.net/icamera0/article/details/50843196

这个我也不知道有什么用...

PIL.Image.fromarray(objmode=None)

利用数组数据创建一块图片内存

If obj is not contiguous, then the tobytes method is called and frombuffer() is used

参数

·obj——数组对象

·mode——使用的模式

返回:一个图片内存

测试程序:

import numpy as np

from PIL import Image

array = np.ones((40,40))*150

img=Image.fromarray(array).convert("RGB").show()

print(array)

print(img.getpixel((30,30)))

这个程序借鉴stackoverflow上网友的回答,显示一块长宽30的图片。用到了numpy,这个模块的功能不要太强大,可以生成数组,矩阵什么的,看到某些函数也让我一头雾水,看来得好好研究了。在这里 np.ones((40,40))*150表示生成一个40行,40列,元素为1numpy数组,后面乘以150表示将数组元素的值都乘以150

之前看到一个程序,是用numpy库的meshgrid生成一个圆的矩阵,这可能涉及到图论里的图的矩阵表示了,我一脸懵比,以后等学numpy库的时候再说吧还是

先写个简单的:

import numpy as np

from PIL import Image

array=[

     0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,

     0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,

     0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,

     0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,

     0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,

     0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,

     0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,

     1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,

     0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,

     0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,

     0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,

     0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,

     0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,

     0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,

     0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,]

nr=np.reshape(array,(15,15))*255

img=Image.fromarray(nr).convert("RGB")

print(nr)

print(img.getpixel((0,7)))

img.show()

img.save("paint.jpg")

这个程序输出nr矩阵是这样
[[ 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 255 0 255 0 0 0 0 0 0]
[ 0 0 0 0 0 255 0 0 0 255 0 0 0 0 0]
[ 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0]
[ 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0]
[ 0 0 255 0 0 0 0 0 0 0 0 0 255 0 0]
[ 0 255 0 0 0 0 0 0 0 0 0 0 0 255 0]
[255 0 0 0 0 0 0 0 0 0 0 0 0 0 255]
[ 0 255 0 0 0 0 0 0 0 0 0 0 0 255 0]
[ 0 0 255 0 0 0 0 0 0 0 0 0 255 0 0]
[ 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0]
[ 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0]
[ 0 0 0 0 0 255 0 0 0 255 0 0 0 0 0]
[ 0 0 0 0 0 0 255 0 255 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0]]
图片是一张长宽15像素,背景黑色,中间有一个旋转90°的方框。在这里也试了一下getpixel,得到一个像素位的颜色值。

posted @ 2019-08-16 14:47  vocus  阅读(2108)  评论(0编辑  收藏  举报