使用 Image 类

可以使用 Image 模块的 open() 方法加载图片文件:

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

操作成功返回 Image 对象。可以通过实例属性查看图片的属性:

#在python2中,像在python3一样使用print()方法
from __future__ import print_function
print(im.format, im.size, im.mode)
# PPM (512, 512) RGB

如果 image 不是从文件读取的, format 属性被设置为 None。mode 属性定义了图片频谱的数量和名称,以及像素类型和深度。常用的模式是灰度图像的“L”(亮度)、真彩色图像的“RGB”和印前图像的“CMYK”。

如果图片 open 失败,会引发 IOError 错误。

一旦实例化了 Image 类,就可以使用它的方法去处理图像。

读写图片

open()

save() 不指定图片格式的话,默认使用原来的格式

把图片的格式转换为 JPEG

from __future__ import print_function
import os, sys
from PIL import Image for infile in sys.argv[1:]:
# Python中 sys.argv[]的用法简明解释
f, e = os.path.splitext(infile)
outfile = f + ".jpg"
if infile != outfile:
try:
Image.open(infile).save(outfile)
except IOError:
print("cannot convert", infile)

将以上代码写进python文件test.py,然后在命令行 python test.py ???1.png ???2.png ???3.png ...,便会生成一个 ???1.jpg,???2.jpg,???3.jpg ... 文件。

生成 JPEG 缩略图

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)

如果 size 比原来大,不会生效;如果一个大一个小,会自动把大的调小。

当打开一个图片的时候,决定图片 format, mode, size 等属性的文件头会被读取,其他的内容将之后处理。这样,意味着 open 操作非常快,只依赖于文件的大小和压缩方式。

识别图片文件

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

剪切、粘贴、合并图片

从图片中拷贝出子图片(矩形)

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

box 的四个坐标分别代表:左,上,右,下。坐标的单位为像素。

处理子图,并粘贴回去

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

粘贴处理后的图像到原图的时候,图片的尺寸必须匹配。子图的尺寸不能扩展到原图之外。但是,二者的 mode 属性可以不一致,子图会在粘贴之前自动转换。(Color transforms)

移动图片(水平方向)

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 图像并且使用透明度参数将会影响它的前景色透明度,而并不会影响它的背景色透明度。

分割和合并bands

PIL 可以操作彩色图片的单个波段。split() 方法可以将图片分割成一组单波段的图片。merge() 方法需要一个 mode 参数和一组图片,将它们合并为一个图片。

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

合成的图片会失真。

几何变换

简单的变换

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) # 逆时针旋转90°
out = im.transpose(Image.ROTATE_180) # 逆时针旋转180°
out = im.transpose(Image.ROTATE_270) # 逆时针旋转270°

transpose(ROTATE) 操作等同于 rotate() 方法把 expand 参数置为 True 时的操作。transform() 方法使用更加普遍。

颜色转换

modes 转换

im = Image.open("hopper.ppm").convert("L")

PIL 支持的图像 mode 可以与 “L” 和 “RGB” 互相转换。如果是转换到其他模式,就需要 “RGB”(常用) 作为过渡

图像增强

过滤

使用过滤器
out = im.filter(ImageFilter.DETAIL)

像素操作

point() 方法用于修改为像素点的值,参数为 function object,每个像素点都会应用该 function

使用像素转换
# multiply each pixel by 1.2
out = im.point(lambda i: i * 1.2)

处理不同bands
# 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)
 expression and 255  如果 expression 为 True,返回 255,如果为 False,则返回 0

增强

使用 ImageEnhance 模块,可以调整图像的对比度、亮度、颜色平衡度和锐度。

图片增强
from PIL import ImageEnhance

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

图像序列

PIL 支持一些图像序列(动画格式),包括 FLI/FLC, GIF等。TIFF 文件可以包含多帧。

open 一个图像序列之后,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

使用 ImageSequence

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

Postscript 打印

绘制 Postscript

from PIL import Image
from PIL import PSDraw im = Image.open("hopper.ppm")
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()

更多关于读取图片的内容

使用 open() 方法打开图片,只需简单的传入文件名作为参数,但是如果打开失败,就会产生 IOError 异常。在此,可以使用 file-like object 代替文件名,object 必须实现了read(), seek() 和 tall() 方法,并且是用二进制方式打开文件。

Reading from an open file

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

Reading from a string

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

如果图片文件嵌入在一个大文件中,可以使用 ContainerIO 和 TarIO 模块处理。

Reading from a tar archive

from PIL import Image, TarIO

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

控制解码器

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

重新配置解码器之后,draft() 方法可以处理打开但未加载的图片。

Reading in draft mode

这种方式只适用于 JPEG 和 MPO 文件。

from PIL import Image
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)

得到的结果图像,可能不完全匹配给定的 mode 和 size。为了确保得到的图片不大于给定的尺寸,可以使用 thumbnail() 方法代替。

Pillow6 起步的更多相关文章

  1. [NodeJS] Hello World 起步教程

    概述: 做数据,免不了需要展示数据,数据可视化是必须经历的步骤. 本文将提供一个NodeJS的起步教程,是笔者这两天探索的小结. 正文:  1. 为什么使用NodeJS 究竟是以B/S还是C/S的架构 ...

  2. Node.js起步 -- (1)

    先来简单介绍nodeJS 我们知道JavaScript是运行在浏览器中的,浏览器为它提供了一个上下文(context),从而让JavaScript得以解析执行. nodeJS其实可以这么理解,它是另外 ...

  3. Linux上的SQL Server的起步

    我们知道,几个星期前,微软发布了在Linux上直接运行的SQL Server第一个公开CTP版本!因此,对我来说,是时候跨界在Linux上安装我的第一个SQL安装,这样的话,我就可以在Linux上折腾 ...

  4. Pro Git 第一章 起步 读书笔记

    Pro Git 笔记 第1章 起步 1.文件的三种状态. 已提交:文件已经保存在本地数据库中了.(commit) 已修改:修改了某个文件,但还没有提交保存.(vim) 已暂存:已经把已修改的文件放在下 ...

  5. 第二篇.Bootstrap起步

    第二篇Bootstrap起步 我们可以在http://getbootstrap.com下载bootstrap的文件 点击左边的download bootstrap可以下载bootstrap的css,j ...

  6. Android学习起步 - 新建工程及相关

    新手起步迷迷糊糊,以下记录迷惑之处,大家共勉!!! 1.创建安卓应用工程 选择Andriod Application Project 点下一步直到完成. 二.下面是新建工程注意的地方 (1)首选删除系 ...

  7. okhttp教程——起步篇

    okhttp教程--起步篇 这篇文章主要总结Android著名网络框架-okhttp的基础使用,后续可能会有关于他的高级使用. okhttp是什么 okhttp是Android端的一个Http客户端, ...

  8. DirectX API 编程起步 #01 项目设置

    =========================================================== 目录: DirectX API 编程起步 #02 窗口的诞生 DirectX A ...

  9. Windows程序设计(第五版)学习:第一章 起步

    第一章 起步 1,windows主要的三个动态库: kernel32.dll负责操作系统的传统工作,包括内存管理.文件输入以及任务管理等. user32.dll负责用户界面的操作,即所有窗口的管理 g ...

随机推荐

  1. bytesToSize

    export function bytesToSize(bytes){ if (bytes === 0) return '0 B' let k = 1024, // or 1000 sizes = [ ...

  2. 含有对象的List集合实现字母数字混合排序

    List<PageData> varList = [{BOMCode=10A, mantotal=4}, {BOMCode=10B, mantotal=1}, {BOMCode=11A, ...

  3. ASP 解析json

    第一个方法是使用 JScript : <script language="jscript" runat="server"> Array.protot ...

  4. selinux的设置包括两个部分: 修改安全上下文和修改策略

    selinux的设置包括两个部分: 修改安全上下文和修改策略 修改安全上下文: chcon = change context: chcon 修改策略: setsebool 策略就是由很多boo类型的变 ...

  5. Guarded Suspension Pattern【其他模式】

    Guarded Suspension Pattern public class GuardedSuspension { /** * Guarded Suspension Pattern[保护悬挂模式] ...

  6. AssertionError: View function mapping is overwriting an existing endpoint function: insertCase

    首先,理解这个错误是什么意思,以及出现的原因: 使用Flask定义URL的时候,如果出现"AssertionError: View function mapping is overwriti ...

  7. python练习题--计算总分平均分操作excel

    ''' 有一个存着学生成绩的文件,里面存的是json串,json串读起来特别不直观,需要你写代码把它都写到excel中,并计算出总分和平均分,json格式如下 { "1":[&qu ...

  8. MVC2: 路由 及 遇到问题记录

    MVC 路由 重定向 问题记录 1)MVC 路由 入口方法: (Global.asax)Application_Start()--->(App_Start/RouteConfig.cs)Regi ...

  9. 008-elasticsearch5.4.3【二】ES使用、ES客户端、索引操作【增加、删除】、文档操作【crud】

    一.ES使用,以及客户端 1.pom引用 <dependency> <groupId>org.elasticsearch.client</groupId> < ...

  10. 接口开发01--mock接口

    开发接口的常见场景: 1.mock接口,模拟一些接口,在别的接口没有开发好的时候,你需要测试,可以先模拟一个假接口来测试.比如常见 2.若需要调用第三方接口时,比如支付接口. 3.查看数据,比如开放数 ...