pip install pillow
Pillow安装成功后,需要用PIL导入:
import PIL
from PIL import Image
Image是最常用的模块。
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()方法可以调用系统自带的图像查看程序显示当前图片,如系统中并未安装相应程序,有执行程序时将无任何显示。
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属性返回的是一个元组。
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种颜色。
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即可实现小变大的需求。
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时优化效果基本已经是公平的重采样。
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度并显示。
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()
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
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
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or
我想获取模块中定义的所有常量的值: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
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数
我一直致力于让我们的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
我有一个Controller,我想为这个Controller创建一个助手,我可以在不包含它的情况下使用它。我尝试像这样创建一个与Controller同名的助手classCars::EnginesController我创建的助手是moduleCars::EnginesHelperdefcheck_fuellogger.debug("chekingfuel")endend我得到的错误是undefinedlocalvariableormethod`check_fuel'for#有没有我遗漏的约定? 最佳答案 如果你真的想在Controll