加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

Python用Pillow(PIL)进行简单的图像操作方法

发布时间:2020-12-17 08:18:10 所属栏目:Python 来源:网络整理
导读:Python用Pillow(PIL)进行简单的图像操作方法 颜色与RGBA值 计算机通常将图像表示为RGB值,或者再加上alpha值(通透度,透明度),称为RGBA值。在Pillow中,RGBA的值表示为由4个整数组成的元组,分别是R、G、B、A。整数的范围0~255。RGB全0就可以表示黑色,全

Python用Pillow(PIL)进行简单的图像操作方法

颜色与RGBA值

计算机通常将图像表示为RGB值,或者再加上alpha值(通透度,透明度),称为RGBA值。在Pillow中,RGBA的值表示为由4个整数组成的元组,分别是R、G、B、A。整数的范围0~255。RGB全0就可以表示黑色,全255代表黑色。可以猜测(255,255)代表红色,因为R分量最大,G、B分量为0,所以呈现出来是红色。但是当alpha值为0时,无论是什么颜色,该颜色都不可见,可以理解为透明。

from PIL import ImageColor
print(ImageColor.getcolor('red','RGBA'))
# 也可以只以RBG的方式查看
print(ImageColor.getcolor('black','RGB'))
(255,255)
(0,0)

图像的坐标表示

图像中左上角是坐标原点(0,0),这和平常数学里的坐标系不太一样。这样定义的坐标系意味着,X轴是从左到右增长的,而Y轴是从上到下增长。

在Pillow中如何使用上述定义的坐标系表示一块矩形区域?许多函数或方法要求提供一个矩形元组参数。元组参数包含四个值,分别代表矩形四条边的距离X轴或者Y轴的距离。顺序是(左,顶,右,底)。右和底坐标稍微特殊,表示直到但不包括。可以理解为[左,右)和[顶, 底)这样左闭右开的区间。比如(3,2,8,9)就表示了横坐标范围[3,7];纵坐标范围[2,8]的矩形区域。

使用Pillow操作图像

了解了一些基础知识,可以上手了。首先从读取图片开始,很多图像处理库(如opencv)都以imread()读取图片。Pillow中使用open方法。

from PIL import Image

im_path = r'F:Jupyter Notebookcsv_time_datetime_PILrabbit.jpg'
im = Image.open(im_path)
width,height = im.size
# 宽高
print(im.size,width,height)
# 格式,以及格式的详细描述
print(im.format,im.format_description)

im.save(r'C:UsersAdministratorDesktoprabbit_copy.jpg')
im.show()
(1920,1080) 1920 1080
JPEG JPEG (ISO 10918)

im.size返回一个元组,分别是宽和高。show()方法会调用系统默认图像查看软件,打开并显示。im.format可查看图像的格式。save()可保存处理后的图片,如果未经处理,保存后的图像占用的空间(字节数)一般也与原图像不一样,可能经过了压缩。

新建图像

Pillow也可以新建空白图像,第一个参数是mode即颜色空间模式,第二个参数指定了图像的分辨率(宽x高),第三个参数是颜色。

可以直接填入常用颜色的名称。如'red'

也可以填入十六进制表示的颜色,如#FF0000表示红色。

还能传入元组,比如(255,255)或者(255, 0, 0)表示红色。

# 通常使用RGB模式就可以了
newIm= Image.new('RGB',(100,100),'red')
newIm.save(r'C:UsersAdministratorDesktop1.jpg')

# 也可以用RGBA模式,还有其他模式查文档吧
blcakIm = Image.new('RGB',(200,'red')
blcakIm.save(r'C:UsersAdministratorDesktop2.jpg')
# 十六进制颜色
blcakIm = Image.new('RGBA','#FF0000')
blcakIm.save(r'C:UsersAdministratorDesktop3.jpg')
# 传入元组形式的RGBA值或者RGB值
# 在RGB模式下,第四个参数失效,默认255,在RGBA模式下,也可只传入前三个值,A值默认255
blcakIm = Image.new('RGB',(255,255,120))
blcakIm.save(r'C:UsersAdministratorDesktop4.jpg')

裁剪图像

Image有个crop()方法接收一个矩形区域元组(上面有提到)。返回一个新的Image对象,是裁剪后的图像,对原图没有影响。

im = Image.open(im_path)
cropedIm = im.crop((700,100,1200,1000))
cropedIm.save(r'C:UsersAdministratorDesktopcropped.jpg')

看下原图和裁剪后的图像。

复制与粘贴图像到另一个图像

Image的copy函数如其名会产生一个原图像的副本,在这个副本上的任何操作不会影响到原图像。paste()方法用于将一个图像粘贴(覆盖)在另一个图像上面。谁调用它,他就在该Image对象上直接作修改。

im = Image.open(im_path)
cropedIm = im.crop((700,1000))
im.paste(cropedIm,(0,0))
im.show()
im.save(r'C:UsersAdministratorDesktoppaste.jpg')

im.show()显示图像发现这时im(即原图)已经被改变。

这如果之后还会用到原图的信息,由于信息被改变就很麻烦。所以paste前最好使用copy()复制一个副本,在此副本操作,不会影响到原图信息。虽然在程序里原图信息已改变,但由于保存文件时用的其他文件名,相当于改变没有生效,所以查看的时候原图还是没有改变的。

im = Image.open(im_path)
cropedIm = im.crop((700,1000))
copyIm = im.copy()
copyIm.paste(cropedIm,0))
im.show()
copyIm.save(r'C:UsersAdministratorDesktoppaste.jpg')

这回再看原图,没有改变了。这就保证了之后再次使用im时,里面的信息还是原汁原味。来看个有趣的例子。

im = Image.open(im_path)
cropedIm = im.crop((700,1000))

crop_width,crop_height = cropedIm.size
width,height = im.size

copyIm = im.copy()
for left in range(0,crop_width):
  for top in range(0,height,crop_height):
    copyIm.paste(cropedIm,(left,top))

copyIm.save(r'C:UsersAdministratorDesktopdupli-rabbit.jpg')

以裁剪后的图像宽度和高度为间隔,在循环内不断粘贴在副本中,这有点像是在拍证件照。

调整图像的大小

resize方法返回指定宽高度的新Image对象,接受一个含有宽高的元组作为参数。宽高的值得是整数。

im = Image.open(im_path)
width,height = im.size
resizedIm = im.resize((width,height+(1920-1080)))
resizedIm.save(r'C:UsersAdministratorDesktopresize.jpg')

兔子瘦了,可以看到resize不是等比例缩放的。

旋转和翻转图像

rotate()返回旋转后的新Image对象,保持原图像不变。逆时针旋转。

im = Image.open(im_path)
im.rotate(90).save(r'C:UsersAdministratorDesktoprotate90.jpg')
im.rotate(270).save(r'C:UsersAdministratorDesktoprotate270.jpg')
im.rotate(180).save(r'C:UsersAdministratorDesktoprotate180.jpg')
im.rotate(20).save(r'C:UsersAdministratorDesktoprotate20.jpg')
im.rotate(20,expand=True).save(r'C:UsersAdministratorDesktoprotate20_expand.jpg')

由上到下,分别是旋转了90°,180°, 270°、普通的20°,加了参数expand=True旋转的20°。expand放大了图像尺寸(变成了2174x1672),使得边角的图像不被裁剪(四个角刚好贴着图像边缘)。再看旋转90°、270°时候图像被裁剪了,但是如下查看图像的宽高,确是和原图一样,搞不懂。

im90 = Image.open(r'C:UsersAdministratorDesktoprotate90.jpg')
im270 = Image.open(r'C:UsersAdministratorDesktoprotate270.jpg')
# 宽高信息并没有改变
print(im90.size,im270.size)
(1920,1080) (1920,1080)

图像的镜面翻转。transpose()函数可以实现,必须传入Image.FLIP_LEFT_RIGHT或者Image.FLIP_TOP_BOTTOM,第一个是水平翻转,第二个是垂直翻转。

im = Image.open(im_path)
im.transpose(Image.FLIP_LEFT_RIGHT).save(r'C:UsersAdministratorDesktoptransepose_lr.jpg')
im.transpose(Image.FLIP_TOP_BOTTOM).save(r'C:UsersAdministratorDesktoptransepose_tb.jpg')

水平翻转看不出来,原图就是水平对称的...

垂直翻转就明显了...

图像过滤

Pillow使用ImageFilter可以简单做到图像的模糊、边缘增强、锐利、平滑等常见操作。

from PIL import Image,ImageFilter

im = Image.open(im_path)
# 高斯模糊
im.filter(ImageFilter.GaussianBlur).save(r'C:UsersAdministratorDesktopGaussianBlur.jpg')
# 普通模糊
im.filter(ImageFilter.BLUR).save(r'C:UsersAdministratorDesktopBLUR.jpg')
# 边缘增强
im.filter(ImageFilter.EDGE_ENHANCE).save(r'C:UsersAdministratorDesktopEDGE_ENHANCE.jpg')
# 找到边缘
im.filter(ImageFilter.FIND_EDGES).save(r'C:UsersAdministratorDesktopFIND_EDGES.jpg')
# 浮雕
im.filter(ImageFilter.EMBOSS).save(r'C:UsersAdministratorDesktopEMBOSS.jpg')
# 轮廓
im.filter(ImageFilter.CONTOUR).save(r'C:UsersAdministratorDesktopCONTOUR.jpg')
# 锐化
im.filter(ImageFilter.SHARPEN).save(r'C:UsersAdministratorDesktopSHARPEN.jpg')
# 平滑
im.filter(ImageFilter.SMOOTH).save(r'C:UsersAdministratorDesktopSMOOTH.jpg')
# 细节
im.filter(ImageFilter.DETAIL).save(r'C:UsersAdministratorDesktopDETAIL.jpg')

另外,若是要进行图案、文字的绘制,可使用ImageDraw。Pillow还有其他强大功能,就不一一列举了。

其实,Pillow只是个基础的图像处理库。若不深入图像处理,已经够用。专业人士使用opencv是更好地选择。Python中使用import cv2开始使用吧!

以上这篇Python用Pillow(PIL)进行简单的图像操作方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持编程小技巧。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读