zoukankan      html  css  js  c++  java
  • Pillow6 起步

    使用 Image 类

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

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

     

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

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

     

    如果 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)
    View Code

    将以上代码写进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)
    View Code

    如果 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
    View Code

    剪切、粘贴、合并图片

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

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

     

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

    处理子图,并粘贴回去

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

    粘贴处理后的图像到原图的时候,图片的尺寸必须匹配。子图的尺寸不能扩展到原图之外。但是,二者的 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
    View Code

     

    至于更多黑魔法,paste方法也可以传入一个表示透明度的可选参数。当你使用了这个黑魔法,传入255这个值将会使图像变得不透明。反之传入0则会使图像完全透明。传入中间值则会使图片半透明。例如,修改一个 RGBA 图像并且使用透明度参数将会影响它的前景色透明度,而并不会影响它的背景色透明度。

    分割和合并bands

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

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

     

    合成的图片会失真。

    几何变换

    简单的变换

    out = im.resize((128, 128))  # 变换后的大小
    out = im.rotate(45)  # 要旋转的大小,逆时针
    View Code

     

    旋转图像

    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°
    View Code

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

    颜色转换

    modes 转换

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

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

    图像增强

    过滤

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

    像素操作

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

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

    处理不同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)
    View Code
     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")
    View Code

    图像序列

    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
    View Code

    使用 ImageSequence

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

    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()
    View Code

    更多关于读取图片的内容

    使用 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)
    View Code

    Reading from a string

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

    如果图片文件嵌入在一个大文件中,可以使用 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)
    View Code

    控制解码器

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

    重新配置解码器之后,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)
    View Code

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

  • 相关阅读:
    如何将自己的镜像上传到私库
    基于spring-cloud的微服务(1) 服务注册中心eureka
    关于对象池技术的一些记录
    为Docker容器中运行的gitlab添加ssh的一些问题记录
    使用java实现的socket代理(支持socket4和socket5)
    ConfluenceRemoteUserAuth
    JiraRemoteUserAuth
    Apache 的mod_auth_cas模块的介绍和使用
    基于乌班图的标准镜像添加中文支持
    apache反向代解决绝对路径可能出现的问题
  • 原文地址:https://www.cnblogs.com/catyuang/p/11195699.html
Copyright © 2011-2022 走看看