PIL(Python Imaging Library)图像处理库教程

236 篇文章 43 订阅
39 篇文章 5 订阅

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.size}x{im.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)

参考

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序媛一枚~

您的鼓励是我创作的最大动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值