PIL(Python Imaging Library)图像处理库教程
Posted 程序媛一枚~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PIL(Python Imaging Library)图像处理库教程相关的知识,希望对你有一定的参考价值。
PIL(Python Imaging Library)图像处理库教程
- open()函数,该库根据文件的内容自动确定格式,除非确实需要,否则库不会解码或加载栅格数据。
open()将读取文件头以确定文件格式并提取解码文件所需的模式、大小和其他属性等内容,但文件的其余部分直到稍后才会处理。
即open()打开图像文件是一项快速操作,它与文件大小和压缩类型无关。 - save()方法,保存文件时,名称很重要。除非指定格式,否则库将使用文件扩展名来发现要使用的文件存储格式
- show()的标准版本不是很有效,因为它将图像保存到临时文件并调用实用程序来显示图像,依赖于已经安装的其他图片查看工具
- convert()在不同像素表示之间转换图像,图片格式转换,B,G,R,L通道等转换 split merge 通道分离及合并
- thumbnails创建缩略图
- crop(), paste()剪切粘贴合并图像
- transpose()翻转图像
- roll()翻转 图像滚动拼接
- 图像类包含resize()和rotate(),前者采用元组给出新大小,后者采用逆时针方向的角度(以度为单位);
- transpose()翻转平移
- 创建MASK imout = im.point(lambda i: expression and
255) - ImageEnhance调整对比度,亮度,色彩平衡和清晰度( contrast, brightness, color
balance and sharpness)。 - PIL包含对图像序列(也称为动画格式)的一些基本支持。支持的序列格式包括 FLI/FLC、GIF 和一些实验格式。TIFF文件还可以包含多个帧;
当打开序列文件时,PIL会自动加载序列中的第一帧。可以使用seek和tell不同帧之间移动;
读取动图并遍历每一帧展示,seek,tell或者ImageSequence.Iterator(im) - 图像文本图形等绘制
- draft()方法操作已打开但尚未加载的图像,使其尽可能接近给定的模式和大小。这是通过重新配置图像解码器来完成的
draft()草稿模式下的阅读仅适用于 JPEG 和 MPO 文件
draft()生成的图像可能与请求的模式和大小不完全匹配。若要确保图像不大于给定大小,请改用缩略图thumbnails方法;
源码
# Python Image Library(PIL)库学习记录
# pil.py
import os
import sys
from pathlib import Path
from urllib.request import urlopen
from PIL import Image, TarIO
from PIL import ImageEnhance # 图像增强:调整对比度,亮度,色彩平衡和清晰度(像素级操作)
from PIL import ImageFilter # 图像过滤:高斯平滑,边缘
from PIL import ImageSequence # 图像读取保存展示,gif等读取,一帧一帧,帧跳转获取等;
from PIL import PSDraw # 图像文本图形图像等绘制
# open()函数,该库根据文件的内容自动确定格式
# save()方法,保存文件时,名称很重要。除非指定格式,否则库将使用文件扩展名来发现要使用的文件存储格式
# 读取保存图片,获取图片属性
def readSave():
# 从文件加载图片
im = Image.open("ml.jpg")
# 以上下文对象方式读取
# with Image.open("hopper.ppm") as im:
# im.show()
# 从打开的文件读取
# with open(’ml.jpg‘, "rb") as fp:
# im = Image.open(fp)
# 从二进制文件读取
# im = Image.open(io.BytesIO(buffer))
# 从url读取
url = "https://python-pillow.org/images/pillow-logo.png"
img = Image.open(urlopen(url))
# 或者使用ContainerIO or TarIO从压缩文件/大文件读取
fp = TarIO.TarIO("Tests/images/hopper.tar", "hopper.jpg")
im = Image.open(fp)
# 像素类型和深度。常见的模式是灰度图像的“L”(亮度),真彩色图像的“RGB”和印前图像的“CMYK”。
print(im.format, im.size, im.mode)
# JPEG (512, 512) RGB
# show()的标准版本不是很有效,因为它将图像保存到临时文件并调用实用程序来显示图像,依赖于已经安装的其他图片查看工具
im.show()
# 图片格式转换
def convert(infile):
# 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(outfile)
except OSError:
print("cannot convert", infile)
# 创建JPEG缩略图(thumbnails)
def thumbnails(infile):
size = (128, 128)
# for infile in sys.argv[1:]:
outfile = os.path.splitext(infile)[0] + ".thumbnail"
if infile != outfile:
try:
# 请务必注意,除非确实需要,否则库不会解码或加载栅格数据。
# 打开文件时,将读取文件头以确定文件格式并提取解码文件所需的模式、大小和其他属性等内容,但文件的其余部分直到稍后才会处理。
# 即open()打开图像文件是一项快速操作,它与文件大小和压缩类型无关。
with Image.open(infile) as im:
im.thumbnail(size)
# im.thumbnail((200, 200), Image.ANTIALIAS)
print("thumbnail =", im.mode, im.size)
im.save(outfile, "JPEG")
im.show()
except OSError:
print("cannot create thumbnail for", infile)
# 下面是一个简单的脚本,用于快速识别一组图像文件:
def identify():
print(sys.argv)
print(sys.argv[1:])
for infile in sys.argv[1:]:
try:
with Image.open(infile) as im:
print(infile, im.format, f"im.sizexim.mode")
except OSError:
pass
# 剪切、粘贴、合并图像
def crop(infile):
im = Image.open(infile)
# 该区域由 4 元组定义,其中坐标为(左、上、右、下)。Python 成像库使用左上角为 (0, 0) 的坐标系。
# 坐标是指像素之间的位置,因此上例中的区域正好为 300x300 像素
box = (100, 100, 400, 400)
# 提取子矩形
region = im.crop(box)
region.show()
# 将区域旋转180°,再粘贴回去
region = region.transpose(Image.ROTATE_180)
im.paste(region, box)
im.show()
def roll(im, delta):
"""横向滚动图像"""
xsize, ysize = im.size
print(xsize, ysize)
delta = delta % xsize
print(delta)
if delta == 0:
return im
part1 = im.crop((0, 0, delta, ysize))
part2 = im.crop((delta, 0, xsize, ysize))
im.paste(part1, (xsize - delta, 0, xsize, ysize))
im.paste(part2, (0, 0, xsize - delta, ysize))
im.show()
# 合并图像
def merge(im1, im2):
w = im1.size[0] + im2.size[0]
h = max(im1.size[1], im2.size[1])
# paste方法还可以将透明度掩码作为可选参数。值255表示粘贴的图像在该位置是不透明的(即,粘贴的图像应按原样使用)。
# 值 0 表示粘贴的图像是完全透明的。介于两者之间的值表示不同的透明度级别。
# 例如,粘贴 RGBA图像并将其用作蒙版将粘贴图像的不透明部分,但不粘贴其透明背景。
im = Image.new("RGBA", (w, h))
im.paste(im1)
im.paste(im2, (im1.size[0], 0))
im.show()
# 分离和合并通道
def mergeSplit(im):
# 单通道图像的话,split方法只返回自身
r, g, b = im.split()
r.show()
g.show()
b.show()
# Image是rgb格式
# im = Image.merge("BGR", (b, g, r))
# im.show()
im = Image.merge("RGB", (r, g, b))
im.show()
# 几何变换
# 图像类包含resize()和rotate()的方法。前者采用元组给出新大小,后者采用逆时针方向的角度(以度为单位)。
# transpose()翻转平移
# convert()在不同像素表示之间转换图像。
def geometricalTransform(im):
out = im.resize((128, 128))
out.show()
# out = im.rotate(45) # degrees counter-clockwise
# out.show()
# out = im.transpose(Image.FLIP_LEFT_RIGHT)
# out.show()
# out = im.transpose(Image.FLIP_TOP_BOTTOM)
# out.show()
# out = im.transpose(Image.ROTATE_90)
# out.show()
# out = im.transpose(Image.ROTATE_180)
# out.show()
out = im.transpose(Image.ROTATE_270)
out.show()
l = im.convert("L")
l.show()
# 图像增强模式 PIL提供了许多可用于增强图像的方法和模块。
# 图像筛选器模块包含许多预定义的增强过滤器,可与 filter()方法一起使用。
def fil(im):
out = im.filter(ImageFilter.DETAIL)
out.show()
# multiply each pixel by 1.2
out = im.point(lambda i: i * 1.2)
out.show()
# 创建MASK
# imout = im.point(lambda i: expression and 255)
def createMask(im):
# 分离图像通道
source = im.split()
R, G, B = 0, 1, 2
# 选择红色区域 < 100
mask = source[R].point(lambda i: i < 100 and 255)
mask.show()
# 处理绿色通道 * 0.7
out = source[G].point(lambda i: i * 0.7)
out.show()
# 粘贴绿色通道到 红色<100的模板
source[G].paste(out, None, mask)
# 构建新的图像
im = Image.merge(im.mode, source)
im.show()
# 对于更高级的图像增强,可以使用“ImageEnhance”模块中的类。从图像创建后,可以使用增强对象快速尝试不同的设置。
# 可以通过这种方式调整对比度,亮度,色彩平衡和清晰度( contrast, brightness, color balance and sharpness)。
def enhancement(im):
enh = ImageEnhance.Contrast(im)
enh.enhance(1.3).show("30% more contrast")
# PIL包含对图像序列(也称为动画格式)的一些基本支持。支持的序列格式包括 FLI/FLC、GIF 和一些实验格式。TIFF文件还可以包含多个帧。
# 当打开序列文件时,PIL会自动加载序列中的第一帧。可以使用seek和tell不同帧之间移动:
def imageSequence(infile):
with Image.open(infile) as im:
im.seek(1) # skip to the second frame
# im.show()
try:
while 1:
print('--: ', im.tell() + 1)
im.seek(im.tell() + 1)
im.show()
# do something to im
except EOFError:
pass # end of sequence
# 读取动图并遍历每一帧展示
def readGif(infile):
im = Image.open(infile)
for i, frame in enumerate(ImageSequence.Iterator(im)):
print(i)
frame.show()
# 图像文本图形等绘制
def drawPostScript(infile):
with Image.open(infile) as im:
title = "hopper"
box = (1 * 72, 2 * 72, 7 * 72, 10 * 72) # in points
ps = PSDraw.PSDraw() # default is sys.stdout or sys.stdout.buffer
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()
im.show()
im.show()
def compress_image(source_path, dest_path):
with Image.open(source_path) as img:
if img.mode != "RGB":
img = img.convert("RGB")
img.save(dest_path, "JPEG", optimize=True, quality=80)
def batchProcess():
paths = Path(".").glob("*.png")
for path in paths:
compress_image(path, path.stem + ".jpg")
# draft()方法操作已打开但尚未加载的图像,使其尽可能接近给定的模式和大小。这是通过重新配置图像解码器来完成的
# 草稿模式下的阅读仅适用于 JPEG 和 MPO 文件
# 请注意: draft()生成的图像可能与请求的模式和大小不完全匹配。若要确保图像不大于给定大小,请改用缩略图thumbnails方法。
def draft(file):
print(file)
with Image.open(file) as im:
print("original =", im.mode, im.size)
im.draft("L", (100, 100))
print("draft =", im.mode, im.size)
infile = '0_viz_float64.png'
infile = 'ml.jpg'
# infile = 'ym.jpeg'
# infile = 'n_100.jpg'
# infile = 'rb.jpeg'
im = Image.open(infile)
im2 = Image.open('ml.jpg')
convert(infile)
thumbnails(infile)
identify()
crop(infile)
roll(im, 540)
merge(im, im2)
mergeSplit(im)
geometricalTransform(im)
fil(im)
createMask(im)
enhancement(im)
gif = 'detect_bright_spots.gif'
imageSequence(gif)
readGif(gif)
drawPostScript(infile)
# batchProcess()
draft(infile)
参考
以上是关于PIL(Python Imaging Library)图像处理库教程的主要内容,如果未能解决你的问题,请参考以下文章
cannot import name '_imaging' 与No module named PIL解决方法