主页 > GUI教程 > 正文

Python图画处理库:Pillow 初级教程

Image类

Pillow中最重要的类便是Image,该类存在于同名的模块中。能够经过以下几种办法实例化:从文件中读取图片,处理其他图片得到,或许直接创立一个图片。

运用Image模块中的open函数翻开一张图片:

>>> from PIL import Image
>>> im = Image.open("lena.ppm")
假如翻开成功,回来一个Image目标,能够经过目标特点查看文件内容
>>> from __future__ import print_function
>>> print(im.format, im.size, im.mode)
PPM (512, 512) RGB

format特点界说了图画的格局,假如图画不是从文件翻开的,那么该特点值为None;size特点是一个tuple,表明图画的宽和高(单位为像素);mode特点为表明图画的形式,常用的形式为:L为灰度图,RGB为真彩色,CMYK为pre-press图画。

假如文件不能翻开,则抛出IOError反常。

当有一个Image目标时,能够用Image类的各个办法进行处理和操作图画,例如显现图片:

>>> im.show()

ps:规范版别的show()办法不是很有功率,由于它先将图画保存为一个临时文件,然后运用xv进行显现。假如没有装置xv,该函数乃至不能作业。可是该办法十分便于debug和test。(windows中应该调用默许图片查看器翻开)

读写图片

Pillow库支撑相当多的图片格局。直接运用Image模块中的open()函数读取图片,而不必先处理图片的格局,Pillow库主动依据文件决议格局。

Image模块中的save()函数能够保存图片,除非你指定文件格局,那么文件名中的扩展名用来指定文件格局。

图片转成jpg格局

from __future__ import print_function
import os, sys
from PIL import Image
for infile in sys.argv[1:]:
    f, e = os.path.splitext(infile)
    outfile = f + ".jpg"
    if infile != outfile:
        try:
            Image.open(infile).save(outfile)
        except IOError:
            print("cannot convert", infile)

save函数的第二个参数能够用来指定图片格局,假如文件名中没有给出一个规范的图画格局,那么第二个参数是有必要的。

创立缩略图

from __future__ import print_function
import os, sys
from PIL import Image
size = (128, 128)
for infile in sys.argv[1:]:
    outfile = os.path.splitext(infile)[0] + ".thumbnail"
    if infile != outfile:
        try:
            im = Image.open(infile)
            im.thumbnail(size)
            im.save(outfile, "JPEG")
        except IOError:
            print("cannot create thumbnail for", infile)

有必要指出的是除非有必要,Pillow不会解码或raster数据。当你翻开一个文件,Pillow经过文件头确认文件格局,巨细,mode等数据,余下数据直到需求时才处理。

这意味着翻开文件十分快,与文件巨细和紧缩格局无关。下面的程序用来快速确认图片特点:

确认图片特点

from __future__ import print_function
import sys
from PIL import Image
for infile in sys.argv[1:]:
    try:
        with Image.open(infile) as im:
            print(infile, im.format, "%dx%d" % im.size, im.mode)
    except IOError:
        pass

裁剪、张贴、与兼并图片

Image类包括还多操作图片区域的办法。如crop()办法能够从图片中提取一个子矩形

从图片中仿制子图画

box = im.copy() #直接仿制图画
box = (100, 100, 400, 400)
region = im.crop(box)

区域由4-tuple决议,该tuple中信息为(left, upper, right, lower)。 Pillow左面体系的原点(0,0)为图片的左上角。坐标中的数字单位为像素点,所以上例中截取的图片巨细为300*300像素^2。

处理子图,张贴回原图

region = region.transpose(Image.ROTATE_180)
im.paste(region, box)

将子图paste回原图时,子图的region有必要和给定box的region符合。该region不能超过原图。而原图和region的mode不需求匹配,Pillow会主动处理。

另一个比如

Rolling an image
def roll(image, delta):
    "Roll an image sideways"
    image = image.copy() #仿制图画
    xsize, ysize = image.size
    delta = delta % xsize
    if delta == 0: return image
    part1 = image.crop((0, 0, delta, ysize))
    part2 = image.crop((delta, 0, xsize, ysize))
    image.paste(part2, (0, 0, xsize-delta, ysize))
    image.paste(part1, (xsize-delta, 0, xsize, ysize))
    return image

别离和兼并通道

r, g, b = im.split()
im = Image.merge("RGB", (b, g, r))

关于单通道图片,split()回来图画自身。为了处理单通道图片,有必要先将图片转成RGB。

几许改换

Image类有resize()、rotate()和transpose()、transform()办法进行几许改换。

简略几许改换

out = im.resize((128, 128))
out = im.rotate(45) # 顺时针视点表明

置换图画

out = im.transpose(Image.FLIP_LEFT_RIGHT)
out = im.transpose(Image.FLIP_TOP_BOTTOM)
out = im.transpose(Image.ROTATE_90)
out = im.transpose(Image.ROTATE_180)
out = im.transpose(Image.ROTATE_270)

transpose()和象的rotate()没有功能不同。

更通用的图画改换办法能够运用transform()

形式转化

convert()办法

形式转化

im = Image.open('lena.ppm').convert('L')

图画增强

Filter

ImageFilter模块包括许多预界说的增强filters,经过filter()办法运用

运用filters

from PIL import ImageFilter
out = im.filter(ImageFilter.DETAIL)

像素点处理

point()办法经过一个函数或许查询表对图画中的像素点进行处理(例如比照度操作)。

像素点改换

# multiply each pixel by 1.2
out = im.point(lambda i: i * 1.2)

上述办法能够运用简略的表达式进行图画处理,经过组合point()和paste()还能挑选性地处理图片的某一区域。

处理独自通道

# split the image into individual bands
source = im.split()
R, G, B = 0, 1, 2
# select regions where red is less than 100
mask = source[R].point(lambda i: i < 100 and 255)
# process the green band
out = source[G].point(lambda i: i * 0.7)
# paste the processed band back, but only where red was < 100
source[G].paste(out, None, mask)
# build a new multiband image
im = Image.merge(im.mode, source)

注意到创立mask的句子:

mask = source[R].point(lambda i: i < 100 and 255)

该句能够用下句表明

imout = im.point(lambda i: expression and 255)

假如expression为假则回来expression的值为0(由于and句子现已能够得出成果了),不然回来255。(mask参数用法:当为0时,保存当时值,255为运用paste进来的值,中心则用于transparency作用)

高档图片增强

对其他高档图片增强,应该运用ImageEnhance模块 。一旦有一个Image目标,运用ImageEnhance目标就能快速地进行设置。 能够运用以下办法调整比照度、亮度、色平衡和锐利度。

图画增强

from PIL import ImageEnhance
enh = ImageEnhance.Contrast(im)
enh.enhance(1.3).show("30% more contrast")

动态图

Pillow支撑一些动态图片的格局如FLI/FLC,GIF和其他一些处于试验阶段的格局。TIFF文件相同能够包括数帧图画。

当读取动态图时,PIL主动读取动态图的榜首帧,能够运用seek和tell办法读取不同帧。

from PIL import Image
im = Image.open("animation.gif")
im.seek(1) # skip to the second frame
try:
    while 1:
        im.seek(im.tell()+1)
        # do something to im
except EOFError:
    pass # end of sequence

当读取到最后一帧时,Pillow抛出EOFError反常。

当时版别只答应seek到下一帧。为了倒回之前,有必要从头翻开文件。

或许能够运用下述迭代器类

动态图迭代器类

class ImageSequence:
    def __init__(self, im):
        self.im = im
    def __getitem__(self, ix):
        try:
            if ix:
                self.im.seek(ix)
            return self.im
        except EOFError:
            raise IndexError # end of sequence
for frame in ImageSequence(im):
    # ...do something to frame...
Postscript Printing

Pillow答应经过Postscript Printer在图片上增加images、text、graphics。

Drawing Postscript
from PIL import Image
from PIL import PSDraw
im = Image.open("lena.ppm")
title = "lena"
box = (1*72, 2*72, 7*72, 10*72) # in points
ps = PSDraw.PSDraw() # default is sys.stdout
ps.begin_document(title)
# draw the image (75 dpi)
ps.image(box, im, 75)
ps.rectangle(box)
# draw centered title
ps.setfont("HelveticaNarrow-Bold", 36)
w, h, b = ps.textsize(title)
ps.text((4*72-w/2, 1*72-h), title)
ps.end_document()

ps:textsize不能用,有谁知道吗

更多读取图片办法

之前提到Image模块的open()函数现已满足日常运用。该函数的参数也能够是一个文件目标。

从string中读取

import StringIO
im = Image.open(StringIO.StringIO(buffer))

从tar文件中读取

from PIL import TarIO
fp = TarIO.TarIO("Imaging.tar", "Imaging/test/lena.ppm")
im = Image.open(fp)

草稿形式

draft()办法答应在不读取文件内容的情况下尽或许(或许不会彻底等于给定的参数)地将图片转成给定形式和巨细,这在生成缩略图的时分十分有用(速度要求比质量高的场合)。

draft形式

from __future__ import print_function
im = Image.open(file)
print("original =", im.mode, im.size)
im.draft("L", (100, 100))
print("draft =", im.mode, im.size)


上一篇:python运用wmi模块获取windows下的体系信息 监控体系
下一篇:python OpenCV 入门教程

PythonTab微信大众号:

Python技能交流合作群 ( 请勿加多个群 ):

群1: 87464755

群2: 333646237

群3: 318130924

群4: 385100854