PIL基本使用方法

来源:互联网 发布:js display 隐藏span 编辑:程序博客网 时间:2024/05/08 09:05

Tutorial

Using the Image Class

  • PIL中最重要的类是Image类,在模块中定义了相同的名称。 您可以通过多种方式创建此类的实例; 通过从文件加载图像(loading images from files),处理其他图像(processing other images)或从头开始创建图像(creating images from scratch)。
    1. 可以使用Image中的open,来从文件中加载图像
#-*- coding: UTF-8 -*- import Imageim = Image.open('/timg.jpg')  # ()里是图片的位置print im.format, im.size, im.输出结果如下:JPEG (319, 204) RGB
  • format属性标识图像的源。 如果图像未从文件中读取,则将其设置为无。
  • size属性是一个包含宽度和高度(以像素为单位)的2元组。
  • mode属性定义图像中的带的数量和名称,以及像素类型和深度。 常用模式是灰度图像的“L”(亮度),真彩色图像的“RGB”,印前图像的“CMYK”。

如果文件无法打开,则会引发IOError异常。

一旦你有一个Image类的实例,你可以使用这个类定义的方法来处理和处理图像。 例如,我们来显示刚加载的图像:

im.show()

(show的标准版本并不是非常有效,因为它将图像保存到临时文件,并调用xv实用程序来显示图像。 如果你没有安装xv,它甚至不会工作。 当它工作时,它是非常方便的调试和测试。)

Reading and Writing Image

PIL 支持各种图像文件格式。 要从磁盘读取文件,请使用图像模块中的打开功能。 您不必知道打开文件的文件格式。 库会根据文件的内容自动确定格式。

要保存文件,请使用Image类的保存方法。 保存文件时,名称变得重要。 除非指定格式,否则库将使用文件扩展名(filename extension)来发现要使用的文件存储格式。

将文件转换为JPEG
import os, sysimport Imagefor 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方法。 如果您使用非标准扩展名,则必须始终以这种方式指定格式:

常见JPEG缩略图

import os, sysimport Imagesize = 128, 128for 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

重要的是要注意,PIL不会解码或加载栅格数据(raster data),除非它真的必须。 打开文件时,会读取文件头以确定文件格式,并提取解码文件所需的模式,大小和其他属性,但是文件的其余部分将不会被处理。

这意味着打开图像文件是一种快速操作,它与文件大小和压缩类型无关。这是一个简单的脚本来快速识别一组图像文件:

Identify Image Files

import sysimport Imagefor infile in sys.argv[1:]:    try:        im = Image.open(infile)        print infile, im.format, "%dx%d" % im.size, im.mode    except IOError:        pass

Cutting, Pasting and Merging Image

Image类包含允许您操纵图像中的区域的方法。 要从图像中提取子矩形,请使用裁剪方法。

从图片中复制一块子矩阵(Copying a subrectangle from an image)

“`
#-- coding: UTF-8 -- #字符转换
import Image

im = Image.open(‘/Users/jacob/Desktop/timg.png’)

box = (100, 100, 150, 150)
region = im.crop(box) # 将子矩阵copy到region中

print “region”, region.size

输出结果:
region (50, 50)
“`
该区域由四元组定义,坐标是(左,上,右,下)。 PIL在左上角使用(0,0)坐标系。 还要注意,坐标是指像素之间的位置。

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

处理一个子矩形,并将其粘贴回来(Processing a subrectangle, and pasting it back)

添加代码:region = region.transpose(Image.ROTATE_180)im.paste(region, box)----------------------------------------------------------------------全部代码:#-*- coding: UTF-8 -*- #字符转换import Imageim = Image.open('/timg.jpg')box = (120, 100, 150, 150)      region = im.crop(box)           region = region.transpose(Image.ROTATE_180)im.paste(region, box)im.save("change.jpg")

原图:

image

变换后:

image

当粘贴区域时,区域的大小必须与给定区域完全匹配。 此外,该区域不能延伸到图像之外。 然而,原始图像和区域的模式不需要匹配。 如果没有,该区域将在粘贴之前自动转换(有关详细信息,请参阅下面的颜色转换部分(Colour Transforms ))。

以下是一个附加实例:

滚动图片(Rolling an image)

添加代码: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(part2, (0, 0, xsize-delta, ysize))    image.paste(part1, (xsize-delta, 0, xsize, ysize))    return image----------------------------------------------------------------------全部代码:#-*- coding: UTF-8 -*- #字符转换import Imagedef 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(part2, (0,0,xsize-delta, ysize))    image.paste(part1, (xsize-delta, 0, xsize, ysize))    return imageim = Image.open('/timg.jpg')change = roll(im, 180)change.save("change_delta_180.jpg")

分别测试 delta = 0、30、60、90、120、150、180图像结果如下:

delta= 0

image

delta= 30

image

delta= 60

image

delta = 90

image

delta = 120

image

delta = 150

image

delta = 180

image

对于更高级的技巧,paste 方法也可以使用透明度掩码作为可选参数。 在该掩码中,值255表示粘贴的图像在该位置是不透明的(即,粘贴的图像应该原样使用)。 值0表示粘贴的图像完全透明。 中间值表示不同的透明度。

PIL还允许您处理多波段图像的各个波段,例如RGB图像。 分割方法创建一组新图像,每个新图像包含来自原始多频带图像的一个波段(band)。 合并功能采用模式和图像元组,并将其组合成新图像。 以下示例交换RGB图像的三个波段:

分裂和合并波段(Splitting and merging bands)

添加代码:r, g, b = im.split()change = Image.merge("RGB", (b, r, g))

请注意,对于单频带图像,分割返回图像本身。 要使用单个色带,您可能需要先将图像转换为“RGB”。

几何变换(Geometrical Transforms)

Image类包含调整图像大小(resize)和旋转(rotate)方法。 前者需要一个给出新尺寸的元组,后者以逆时针方向的角度。

单一几何变换(Simple geometry transforms)

添加代码:out = im.resize((128, 128))out = im.rotate(45) # 逆时针旋转----------------------------------------------------------------------全部代码:1. 只使用 resize#-*- coding: UTF-8 -*- #字符转换import Imageim = Image.open('/timg.jpg')print "原图像大小:    " ,im.sizeout = im.resize((128, 128))print "改变后的图像大小:" ,out.size------------------------------------输出结果:                           原图像大小:      (319, 204)改变后的图像大小: (128, 128)-----------------------------------2. 只使用 rotate#-*- coding: UTF-8 -*- #字符转换import Imageim = Image.open('/timg.jpg')print "原图像大小:    " ,im.sizeout = im.rotate(45)print "改变后的图像大小:" ,out.size-----------------------------------输出结果:原图像大小:      (319, 204)改变后的图像大小: (319, 204)-----------------------------------3. 先使用 resize 后使用 rotate#-*- coding: UTF-8 -*- #字符转换import Imageim = Image.open('/timg.jpg')print "原图像大小:    " ,im.sizeout = im.resize((128, 128))out = im.rotate(45)print "改变后的图像大小:" ,out.sizeout.save("changeResizeThenRotate.jpg")-----------------------------------输出结果:原图像大小:      (319, 204)改变后的图像大小: (319, 204)输出图像: 见下图changeResizeThenRotate-----------------------------------4. 先使用 rotate 后使用 resize#-*- coding: UTF-8 -*- #字符转换import Imageim = Image.open('/timg.jpg')print "原图像大小:    " ,im.sizeout = im.rotate(45)out = im.resize((128, 128))print "改变后的图像大小:" ,out.sizeout.save("changeRotateThenResize.jpg")-----------------------------------输出结果:原图像大小:   (319, 204)改变后的图像大小: (128, 128)输出图像:见下图changeRotateThenResize-----------------------------------

changeResizeThenRotate

image

changeRotateThenResize

image

观察得出: resize 和 rotate 组合使用的时候前一个功能未使用,只使用了后一个功能。【为什么是这样还为解决,待补充】

要以90度步进旋转图像,您可以使用rotate方法或transpose方法。 后者也可用于在其水平或垂直轴上翻转图像。

调换图像(Transposing an image)

添加代码: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)----------------------------------------------------------------------全部代码:#-*- coding: UTF-8 -*- #字符转换import Imageim = Image.open('/timg.jpg')out = im.transpose(Image.FLIP_LEFT_RIGHT)out.save("liftRight.jpg")

转置(ROTATE)和相应的旋转操作之间的性能或结果没有差异。

可以通过变换方法进行更一般的图像变换形式。 有关详细信息,请参阅参考 Transfrom 部分。

颜色转换(Colour Transforms)

PIL允许您使用convert函数在不同像素表示之间转换图像。

模式间转换(Converting between modes)

添加代码:out = im.convert("L")----------------------------------------------------------------全部代码:#-*- coding: UTF-8 -*- #字符转换import Imageim = Image.open('/timg.jpg')print "原始图像:    ", im.modeout = im.convert("L")print "转换后图像:   ", out.mode--------------------------------输出结果:原始图像:     RGB转换后图像:    L--------------------------------

PIL支持每种支持的模式与“L”和“RGB”模式之间的转换。 要在其他模式之间进行转换,您可能需要使用中间图像(通常为“RGB”图像)。

图像增强(Image Enhancement)

PIL提供了许多可用于增强图像的方法和模块。

过滤(Filters)

ImageFilter模块包含许多预定义的增强过滤器,可用于过滤方法。

提供过滤器(Applying filters)
#-*- coding: UTF-8 -*- #字符转换import Imageimport ImageFilterim = Image.open('/timg.jpg')out = im.filter(ImageFilter.DETAIL)out.save("filter.jpg")

点操作(Point Operations)

点法可用于平移图像的像素值(例如,图像对比度操纵)。 在大多数情况下,可以将期望一个参数的函数对象传递给该方法。 根据该功能处理每个像素:

Applying point transforms
添加代码:out = im.point(lambda i: i * 5)----------------------------------------------------------------全部代码:#-*- coding: UTF-8 -*- #字符转换import Imageim = Image.open('/Users/jacob/Desktop/timg.png')out = im.point(lambda i: i * 5)out.save("point5.jpg")--------------------------------输出结果:见下图:point5

point5

image

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

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

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

Python仅评估逻辑表达式的部分,以确定结果所需,并返回作为表达式结果检查的最后一个值。 所以如果上面的表达式是false(0),Python不会看第二个操作数,因此返回0.否则返回255。

增强(Enhancement)

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

您可以这样调整对比度,亮度,色彩平衡和清晰度。

增强图片(Enhancing image)
import ImageEnhanceenh = ImageEnhance.Contrast(im)enh.enhance(1.3).show("30% more contrast")
0 0
原创粉丝点击