Pillow快速入门

Pillow快速入门

前言

本教程目的

学习该库,目的是为了用python去操作图像提供更为全面的选择。

本库进阶学习

进阶学习,首先需要很明确了解要对图像进行什么操作,然后查询相关的API

初学思维导图

在这里插入图片描述


接下来就是初学者教程。

使用 Image Class

PIL中,最重要的类就是Image这个和模块名相同的类。您可以通过多种方式创建该类的实例;要么从文件中加载图像,要么处理其他图像,要么从头创建图像。

要从文件中加载图像,请使用图像模块中的open()函数:

from PIL import Image
im = Image.open("hopper.ppm")

如果成功,此函数将返回一个图像对象。你现在可以使用实例属性来检查文件内容:

print(im.format, im.size, im.mode)
# PPM (512, 512) RGB

读写图像

Python图像库支持多种图像文件格式。要从磁盘读取文件,请使用图像模块中的open()函数。你不必知道打开一个文件的格式。库根据文件的内容自动确定格式。

保存目标格式的图像

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:
            with Image.open(infile) as im:
              	# 核心是im.save()
                im.save(outfile)
        except IOError:
            print("cannot convert", infile)

创建缩略图

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:
            with Image.open(infile) as im:
                #此处在缓冲区生成size大小的thumbnail()
                im.thumbnail(size)
                im.save(outfile, "JPEG")
        except IOError:
            print("cannot create thumbnail for", infile)

需要注意的是,除非必要,否则库不会解码或加载光栅数据。当您打开一个文件时,将读取文件头以确定文件格式,并提取解码文件所需的模式、大小和其他属性,但是文件的其余部分直到稍后才处理。

识别一系列的文件

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

裁剪、复制、拼接图像

从图像中复制子矩形

box = (100, 100, 400, 400)
region = im.crop(box)

区域由一个4元组定义,其中的坐标是(左、上、右、下)。Python图像库使用左上角的坐标系统(0,0)。还要注意,坐标是指像素之间的位置,所以上面例子中的区域就是300x300像素。

现在可以以某种方式处理该区域并将其粘贴回去。

处理子矩形,并将其粘贴回去

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

当粘贴区域时,区域的大小必须与给定的区域完全匹配。此外,区域不能延伸到图像之外。但是,原始图像的模式和区域不需要匹配。如果没有,则在粘贴之前自动转换区域。

平移和拼接图像

def roll(image, delta):
    """Roll an image sideways."""
    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(part1, (xsize-delta, 0, xsize, ysize))
    image.paste(part2, (0, 0, xsize-delta, ysize))

    return image

对于更高级的技巧,paste方法还可以将透明蒙版作为可选参数。

在这个掩码中,值255表示粘贴后的图像在那个位置是不透明的(即,应该按原样使用粘贴后的图像)。值0表示粘贴的图像是完全透明的。中间值表示不同的透明度级别。例如,粘贴RGBA图像并将其用作掩码将粘贴图像的不透明部分,但不粘贴其透明的背景。

Python图像库还允许您处理多波段图像的单个波段,例如RGB图像。分割方法创建一组新图像,每个图像包含原始多频带图像中的一个频带。merge函数接受一个模式和一个图像元组,并将它们组合成一个新图像。下面的例子交换了一个RGB图像的三个波段:

分割和融合波段信息

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

注意,对于单波段图像,split()返回图像本身。要使用单独的颜色带,您可能需要首先将图像转换为“RGB”。

几何变换

PIL.Image。Image类包含调整()和旋转()图像的方法。前者采用一个元组提供新的大小,而后者采用逆时针角度。

简单的几何变换

out = im.resize((128, 128))
out = im.rotate(45) # degrees counter-clockwise

要将图像旋转90度,可以使用rotate()方法或转置()方法。后者也可以用来翻转图像的水平或垂直轴。

翻转图像

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)操作也可以和rotate进行相同的操作。

如果expandTrue则原图像做相应的修改。

更加通用的操作是通过transform()方法对其进行修改。

颜色(通道)转换

Python图像库允许您使用convert()方法在不同的像素表示之间转换图像。

模式之间的转换

from PIL import Image
with Image.open("hopper.ppm") as im:
    im = im.convert("L")

该库支持在每个支持模式与“L”和“RGB”模式之间进行转换。要在其他模式之间进行转换,您可能必须使用中间图像(通常是“RGB”图像)。

图象增强

Python图像库提供了许多可以用来增强图像的方法和模块。

滤波

imageFilter模块包含许多预定义的增强过滤器,可以与filter()方法一起使用.

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)

注意用于创建掩码的语法:

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

图像增强

对于更高级的图像增强,您可以使用ImageEnhance模块中的类。从图像创建后,可以使用增强对象快速尝试不同的设置。

你可以通过这种方式调整对比度、亮度、色彩平衡和锐度。

from PIL import ImageEnhance

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

图像序列

Python图像库包含对图像序列(也称为动画格式)的一些基本支持。支持的序列格式包括FLI/FLC、GIF和一些实验格式。TIFF文件也可以包含一个以上的帧。

当你打开一个序列文件时,PIL会自动加载序列中的第一帧。你可以使用查找和告诉方法在不同的帧之间移动:

序列读取

from PIL import Image

with Image.open("animation.gif") as im:
    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

使用ImageSequence迭代器类

from PIL import ImageSequence
for frame in ImageSequence.Iterator(im):
    # ...do something to frame...

图像打印

Python图像库包括在Postscript打印机上打印图像、文本和图形的函数。这里有一个简单的例子:

from PIL import Image
from PIL import PSDraw

with Image.open("hopper.ppm") as im:
    title = "hopper"
    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 title
    ps.setfont("HelveticaNarrow-Bold", 36)
    ps.text((3*72, 4*72), title)

    ps.end_document()

关于读取图像

我们可以使用上下文管理器去读取图像进行一系列的操作:

from PIL import Image
with Image.open("hopper.ppm") as im:
    ...

您可以使用类似文件的对象来代替文件名。该对象必须实现read()、seek()和tell()方法,并以二进制模式打开。

从打开的文件中读取图像

from PIL import Image
with open("hopper.ppm", "rb") as fp:
    im = Image.open(fp)

从二进制文件中读取

要从二进制数据中读取图像,使用BytesIO类:

from PIL import Image
import io
im = Image.open(io.BytesIO(buffer))

从压缩文件中读取图像

注意,库在读取图像头之前会回滚文件(使用seek(0))。此外,在读取图像数据时也将使用seek(通过load方法)。如果图像文件嵌入到更大的文件中,例如tar文件,则可以使用ContainerIOTarIO模块来访问它。

from PIL import Image, TarIO

fp = TarIO.TarIO("Tests/images/hopper.tar", "hopper.jpg")
im = Image.open(fp)

控制编码器

一些解码器允许您在从文件中读取图像时操作图像。当创建缩略图(速度通常比质量更重要)和在单色激光打印机上打印(只需要图像的灰度版本)时,这通常可以用来加快解码速度。

draft()方法操作打开但尚未加载的图像,使其尽可能接近给定的模式和大小。这是通过重新配置图像解码器实现的。

使用draft()读取图像

这只在JPEGMPO文件情况下适用。此方法操作打开但尚未加载的图像,使其尽可能接近给定的模式和大小。

from PIL import Image

with Image.open(file) as im:
    print("original =", im.mode, im.size)

    im.draft("L", (100, 100))
    print("draft =", im.mode, im.size)
"""
输出:
original = RGB (512, 512)
draft = L (128, 128)
"""

注意,生成的图像可能与请求的模式和大小不完全匹配。要确保图像不大于给定的大小,请使用缩略图方法。


Link

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值