草庐IT

Pillow 图片处理模块

amwkvi 2023-03-28 原文

Pillow 图片处理模块

Pillow是Python第三方库,Python2中有一个叫PIL(Python Imaging Library)的标准库,但不支持Python3,所以一些志愿者在PIL的基础上创建了Pillow,支持Python3。Pillow支持动态图像编辑。

  1. 安装Pillow

    pip install pillow

    Pillow安装成功后,需要用PIL导入:

    import PIL

    from PIL import Image

    Image是最常用的模块。

  2. 打开或者新建一张图片

    import PIL
    from PIL import Image
    pic = Image.open('11.jpg')
    pic.show()
    im = Image.new('RGB', (480, 640), ('pink'))
    im.show()
    

    Image.new()方法有三个参数:图像模式(RGB),图像尺寸(宽,高),颜色(red,green,blue),颜色可以直接用#0000FF或者blue表示蓝色。

    Image.show()方法可以调用系统自带的图像查看程序显示当前图片,如系统中并未安装相应程序,有执行程序时将无任何显示。

  3. Image模块的常用属性

    print('宽:', pic.width)  # 宽: 1361
    print('高:', pic.height)  # 高: 1814
    print('尺寸:', pic.size)  # 尺寸: (1361, 1814)
    print('色彩模式:', pic.mode)  # 色彩模式: RGB
    print('图像格式:', pic.format)  # 图像格式: JPEG
    # print('图片类别:', pic.category)
    print('只读:', pic.readonly)  # 只读: 1
    print('图片信息:', pic.info)  # 图片信息: {'jfif': 257, 'jfif_version': (1, 1), 'jfif_unit': 0, 'jfif_density': (1, 1)}
    

    其中size属性返回的是一个元组。

  4. Image.convert()方法进行图像模式(mode)转换,支持以下标准模式:

    convert(self, mode=None, matrix=None, dither=None, palette=WEB, colors=256): 将当前图片转换为指定的模式,并且返回转换后的图片。

    如果不指定模式,则选择一种能保留图片所有信息且不使用调色板的模式(通常的结果是不转换)。

    mode 描述
    1 1位像素,黑白,每字节存储一个像素
    L 8位像素,黑白
    P 8位像素,使用调色板映射到任何其他模式
    RGB 3x8位像素,真彩色
    RGBA 4x8位像素,带透明蒙版的真彩色
    CMYK 4x8位像素,分色
    YCbCr 3x8位像素,彩色视频格式
    LAB 3x8位像素,L * a * b颜色空间
    HSV 3x8位像素,色相,饱和度,值颜色空间
    I 32位有符号整数像素
    F 32位浮点像素

    1位像素的范围是0-1,0表示黑1表示白,中间表示灰。8位像素的范围是0-255,如RGB的(0, 0, 0)表示黑,(255, 255, 255)表示白,依此类推。

    pic1 = pic.convert('1')
    pic1.show()
    

    convert()方法有5个参数,都有默认值,根据转换的模式来传值:

    mode,图片的模式,传入需要转换的模式。部分模式之间不支持转换,代码会报错。

    matrix, 转换矩阵。传入该参数时,应该传入由浮点数构成的元组,元组长度为4或12。matrix只支持从少数模式转换成'L'或'RGB'。

    dither, 高频振动,用于控制颜色抖动。从模式'RGB'转换为'P'或从'RGB'或'L'转换为'1'时使用。可用的方法有'NONE'或'FLOYDSTEINBERG'(默认)。当提供了matrix参数时不使用此功能。

    palette, 调色板,用于控制调色板的产生。从模式'RGB'转换为'P'时使用,可用的方法有'WEB'(默认)或'ADAPTIVE'。'ADAPTIVE'表示使用自适应的调色板。

    colors, 自适应调色板使用的颜色数。当palette参数为'ADAPTIVE'时,用于控制调色板的颜色数目。默认是最大值,即256种颜色。

  5. 图片的复制、粘贴和保存

    pic = Image.open('11.jpg')
    im = Image.new('RGB', (128, 128), (255, 0, 0))
    im1 = Image.new('RGBA', (128, 128), (0, 0, 255))
    pic1 = pic.copy()
    pic1.paste(im, (640, 600), mask=im1)
    pic1.save('22.jpg', quality=95, subsampling=0)
    

    Image.copy()方法:将指定对象复制并返回。

    Image.paste(im,(行,列),mask=None):在当前图片对象基础上,把im对象粘贴到指定位置,mask参数指定蒙板。

    Image.save()方法:保存当前图片对象到指定位置。

    具体说明

    copy(): 拷贝当前的图片,拷贝出来的图片与原图一模一样。如果想在图片上粘贴一些内容,又想保留原图时,可以使用此方法。

    paste(im, box=None, mask=None): 将另一张图片粘贴到当前图片中,如果粘贴的模式不匹配,则将被粘贴图片的模式转换成当前图片的模式。有3个参数。

    im, 被粘贴的图片。传入一张图片,当第二个参数box指定的是一个区域时,im参数也可以是一个整数或颜色值(元组表示,16进制表示和颜色名都可以,如上面代码中的image_new可以换成(0, 0, 255), '#0000FF', 'blue')。

    box, 图片粘贴的位置或区域。传入一个长度为2或4的元组,如果不传值,默认为(0, 0),图片被粘贴在当前图片的左上角。如果传入长度为2的元组(x, y),表示被粘贴图片的左上角坐标位置。如果传入长度为4的元组(x1, y1, x2, y2),表示图片粘贴的区域,此时区域的大小必须与被粘贴图片一致,否则会报错,传入的元组长度为其他值也会报错。

    mask, 蒙版。传入一张与被粘贴图片尺寸一样的图片,可以使用模式为'1'、'L'或者'RGBA'的图像。如果mask图像的颜色值为255,则直接按被粘贴图片的颜色粘贴,如果mask图像的颜色值为0,则保留当前图片的颜色(相当于没有粘贴),如果mask图像的颜色值为0~255之间的值,则将im与mask进行混合后再粘贴。

    save(fp, format=None, quality=95, subsampling=0): 将当前图片按指定的文件名保存,运行后会将图片按新名字保存在当前路径下(也可以指定路径)。文件名最好带扩展名,方便打开,format表示图片的格式,没有指定format则会根据扩展名来解析(如果能解析出来),一般不需要指定format,传入一个规范的文件名即可。quality:压缩比,默认是75。subsampling:可选参数为0,1,2;选择0即可实现小变大的需求。

  6. 图片裁剪和缩放

    pic = Image.open('11.jpg')
    im_crop = pic.crop(box=(200, 200, 680, 840))
    im_crop.show()
    im_resize = pic.resize((480, 640),reducing_gap=2)
    im_resize.show()
    

    im_crop = pic.crop(box=(200, 200, 680, 840)):裁剪图片,box参数中的四个数字为图片坐标,分别是x1,y1,x2,y2。

    im_resize = pic.resize((480, 640),reducing_gap=2)

    crop(box=None):裁剪图片,返回裁剪区域的图片。box表示裁剪的区域,传入长度为4的元组(x1, y1, x2, y2),不传默认为拷贝原图,相当于copy()方法,如果裁剪的区域超过了原图的区域,超出部分用像素格填充。

    resize(size, resample=BICUBIC, box=None, reducing_gap=None): 缩放图片,返回缩放后的图片。有4个参数。

    size, 图片缩放后的尺寸,传入一个长度为2的元组(width, height)。

    resample, 重采样,是一个可选的重采样过滤器。可以传入Image.NEAREST, Image.BOX, Image.BILINEAR, Image.HAMMING, Image.BICUBIC, Image.LANCZOS。默认过滤器为Image.BICUBIC。如果图像的模式为'1'或'P',则始终设置为Image.NEAREST。

    box, 缩放图片的区域。传入长度为4的元组(x1, y1, x2, y2),这个区域必须在原图的(0, 0, width, height)范围内,如果超出范围会报错,如果不传值则默认将整张原图进行缩放。

    reducing_gap, 减少间隙。传入一个浮点数,用于优化图片缩放效果,默认不进行优化,值大于3.0时优化效果基本已经是公平的重采样。

  7. 图片旋转和翻转

    • rotate()方法:将图片对象进行旋转,可以实现顺时针或逆时针任意角度。
    • transpose()方法:将图片对象进行顺时针或逆时针90度旋转或者翻转,区别于上面的方法不能任意角度,但可以进行垂直或水平翻转。 ★★★★★这个方法比较常用,但根据系统提示在Pillow10(2023-07-01)更新后会停用现在的方法。
    im_resize.rotate(45).show()         # 图片向左(逆时针)旋转45度并显示。
    im_resize.transpose(Image.FLIP_LEFT_RIGHT).show()   # 逆时针旋转90度并显示。
    im_resize.transpose(Image.FLIP_TOP_BOTTOM).show()   # 逆时针旋转90度并显示。
    im_resize.transpose(Image.ROTATE_90).show()     # 逆时针旋转90度并显示。
    im_resize.transpose(Image.ROTATE_180).show()    # 逆时针旋转90度并显示。
    im_resize.transpose(Image.ROTATE_270).show()    # 逆时针旋转90度并显示。
    
  8. 图片特效

    Pillow提供一些简单的图片特效使用,需要从PIL库中导入ImageFilter模块。

     pic = Image.open('11.jpg')
     def pic_filter(imfile, x):
         filters = [
             ImageFilter.BLUR,   # 模糊效果
             ImageFilter.DETAIL, # 细节效果
             ImageFilter.CONTOUR,    # 轮廓效果
             ImageFilter.EDGE_ENHANCE,   # 边缘增强(比锐化更好)
             ImageFilter.EDGE_ENHANCE_MORE,  # 进一步边缘增强
             ImageFilter.FIND_EDGES, # 查找边缘
             ImageFilter.EMBOSS,     # 浮雕效果
             ImageFilter.SHARPEN,    # 锐化
             ImageFilter.SMOOTH,     # 平滑
             ImageFilter.SMOOTH_MORE,    # 进一步平滑
         ]
     return imfile.filter(filters[x]) # 根据列表序号选择效果并显示
     pic_filter(pic,3).show()
    

有关Pillow 图片处理模块的更多相关文章

  1. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  2. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  3. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  4. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  5. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

  6. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  7. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  8. ruby-on-rails - Ruby on Rails - 为文本区域和图片生成列 - 2

    我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数

  9. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  10. ruby-on-rails - Controller 中的 Rails 辅助模块 - 2

    我有一个Controller,我想为这个Controller创建一个助手,我可以在不包含它的情况下使用它。我尝试像这样创建一个与Controller同名的助手classCars::EnginesController我创建的助手是moduleCars::EnginesHelperdefcheck_fuellogger.debug("chekingfuel")endend我得到的错误是undefinedlocalvariableormethod`check_fuel'for#有没有我遗漏的约定? 最佳答案 如果你真的想在Controll

随机推荐