Swift51.com
麦子学院 头像
麦子学院  2017-07-10 12:17

Python学习之使用Pillow(PIL)进行图像操作方法详解

回复:0  查看:3693  

本文和大家分享的主要是python中使用Pillow(PIL)对图像操作相关内容,一起来看看吧,希望对大家学习python有所帮助。

  颜色与RGBA

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

  from PIL import ImageColor

  print(ImageColor.getcolor('red', 'RGBA'))# 也可以只以RBG的方式查看

  print(ImageColor.getcolor('black', 'RGB'))

  (255, 0, 0, 255)

  (0, 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 Notebook\\csv_time_datetime_PIL\\rabbit.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:\\Users\\Administrator\\Desktop\\rabbit_copy.jpg')

  im.show()

  (1920, 1080) 1920 1080

  JPEG JPEG (ISO 10918)

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

  新建图像

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

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

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

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

  # 通常使用RGB模式就可以了

  newIm= Image.new('RGB', (100, 100), 'red')

  newIm.save(r'C:\\Users\\Administrator\\Desktop\\1.png')

  # 也可以用RGBA模式,还有其他模式查文档吧

  blcakIm = Image.new('RGB',(200, 100), 'red')

  blcakIm.save(r'C:\\Users\\Administrator\\Desktop\\2.png')# 十六进制颜色

  blcakIm = Image.new('RGBA',(200, 100), '#FF0000')

  blcakIm.save(r'C:\\Users\\Administrator\\Desktop\\3.png')# 传入元组形式的RGBA值或者RGBRGB模式下,第四个参数失效,默认255,在RGBA模式下,也可只传入前三个值,A值默认255

  blcakIm = Image.new('RGB',(200, 100), (255, 255, 0, 120))

  blcakIm.save(r'C:\\Users\\Administrator\\Desktop\\4.png')

  裁剪图像

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

  im = Image.open(im_path)

  cropedIm = im.crop((700, 100, 1200, 1000))

  cropedIm.save(r'C:\\Users\\Administrator\\Desktop\\cropped.png')

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

Python学习之使用Pillow(PIL)进行图像操作方法详解

Python学习之使用Pillow(PIL)进行图像操作方法详解

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

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

  im = Image.open(im_path)

  cropedIm = im.crop((700, 100, 1200, 1000))

  im.paste(cropedIm, (0, 0))

  im.show()

  im.save(r'C:\\Users\\Administrator\\Desktop\\paste.png')

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

Python学习之使用Pillow(PIL)进行图像操作方法详解

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

  im = Image.open(im_path)

  cropedIm = im.crop((700, 100, 1200, 1000))

  copyIm = im.copy()

  copyIm.paste(cropedIm, (0, 0))

  im.show()

  copyIm.save(r'C:\\Users\\Administrator\\Desktop\\paste.png')

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

  im = Image.open(im_path)

  cropedIm = im.crop((700, 100, 1200, 1000))

  crop_width, crop_height = cropedIm.size

  width, height = im.size

  copyIm = im.copy()for left in range(0, width, crop_width):

  for top in range(0, height, crop_height):

  copyIm.paste(cropedIm, (left, top))

  copyIm.save(r'C:\\Users\\Administrator\\Desktop\\dupli-rabbit.png')

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


Python学习之使用Pillow(PIL)进行图像操作方法详解

调整图像的大小

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

  im = Image.open(im_path)

  width, height = im.size

  resizedIm = im.resize((width, height+(1920-1080)))

  resizedIm.save(r'C:\\Users\\Administrator\\Desktop\\resize.png')


Python学习之使用Pillow(PIL)进行图像操作方法详解

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

  旋转和翻转图像

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

  im = Image.open(im_path)

  im.rotate(90).save(r'C:\\Users\\Administrator\\Desktop\\rotate90.png')

  im.rotate(270).save(r'C:\\Users\\Administrator\\Desktop\\rotate270.png')

  im.rotate(180).save(r'C:\\Users\\Administrator\\Desktop\\rotate180.png')

  im.rotate(20).save(r'C:\\Users\\Administrator\\Desktop\\rotate20.png')

  im.rotate(20, expand=True).save(r'C:\\Users\\Administrator\\Desktop\\rotate20_expand.png')


Python学习之使用Pillow(PIL)进行图像操作方法详解

Python学习之使用Pillow(PIL)进行图像操作方法详解


Python学习之使用Pillow(PIL)进行图像操作方法详解

Python学习之使用Pillow(PIL)进行图像操作方法详解

Python学习之使用Pillow(PIL)进行图像操作方法详解

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

  im90 = Image.open(r'C:\\Users\\Administrator\\Desktop\\rotate90.png')

  im270 = Image.open(r'C:\\Users\\Administrator\\Desktop\\rotate270.png')# 宽高信息并没有改变

  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:\\Users\\Administrator\\Desktop\\transepose_lr.png')

  im.transpose(Image.FLIP_TOP_BOTTOM).save(r'C:\\Users\\Administrator\\Desktop\\transepose_tb.png')


Python学习之使用Pillow(PIL)进行图像操作方法详解

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


Python学习之使用Pillow(PIL)进行图像操作方法详解

垂直翻转就明显了...

  图像过滤

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

  from PIL import Image, ImageFilter

  im = Image.open(im_path)# 高斯模糊

  im.filter(ImageFilter.GaussianBlur).save(r'C:\\Users\\Administrator\\Desktop\\GaussianBlur.jpg')# 普通模糊

  im.filter(ImageFilter.BLUR).save(r'C:\\Users\\Administrator\\Desktop\\BLUR.jpg')# 边缘增强

  im.filter(ImageFilter.EDGE_ENHANCE).save(r'C:\\Users\\Administrator\\Desktop\\EDGE_ENHANCE.jpg')# 找到边缘

  im.filter(ImageFilter.FIND_EDGES).save(r'C:\\Users\\Administrator\\Desktop\\FIND_EDGES.jpg')# 浮雕

  im.filter(ImageFilter.EMBOSS).save(r'C:\\Users\\Administrator\\Desktop\\EMBOSS.jpg')# 轮廓

  im.filter(ImageFilter.CONTOUR).save(r'C:\\Users\\Administrator\\Desktop\\CONTOUR.jpg')# 锐化

  im.filter(ImageFilter.SHARPEN).save(r'C:\\Users\\Administrator\\Desktop\\SHARPEN.jpg')# 平滑

  im.filter(ImageFilter.SMOOTH).save(r'C:\\Users\\Administrator\\Desktop\\SMOOTH.jpg')# 细节

  im.filter(ImageFilter.DETAIL).save(r'C:\\Users\\Administrator\\Desktop\\DETAIL.jpg')

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

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

 

 

来源:博客园