生活不易且无趣,一起找点乐子吧。欢迎评论,和文章无关的也可以。
上次的那篇文章里,我们最后说到了,Image的merge方法,合并。有些地方说的并不准确,我再重新说下。剩余一些其他的方法,这里也捎带着一起说了。
一、filter方法:
过滤器,这个东西大家python里面经常用吧。过滤掉,或者过滤出某些我们想要的东西。ImageFilter类里有个DETAIL属性,“细节”是吧。例子里把它当做了参数:
from PIL import Image
from PIL import ImageFilter
def filter(file):
im = Image.open(file)
out = im.filter(ImageFilter.DETAIL)
out.save('filter.jpg')
简单来说就是用过滤器细节处理,可能对某些图片有不错的效果,我这里还是拿他做下效果吧。
这是原图,接下来是处理后的:
感觉被骗了是不是,但其实你仔细看下,尤其的画笔的边缘描线,是比原图要清晰的。(胡扯!)
二、point方法
我们知道图片都是有一个个像素点构成的,这个方法就是对一个个的像素点进行处理的方法。
def popa(file):#point paste
im = Image.open(file)
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)
im.save('popa.jpg')
我拿官网上的这个例子给大家说下,这里也有我上次说的不那么好的地方,所以这次努努力,说的还不如上一次,haaa。首先将Image对象split,这里就是把色道分离出来,这张图片得mode是RGB,也就是说单独的把这三个色道分离出来,分离出来的色道图片也是可以直接save的,我这里就不做测试了,大家可以去试下。Image对象split完后返回tuple元组类型,所以下面用index引用也就不难理解了吧。因为元组是有序的嘛,所以这里的r,g,b变量的赋值,也只是为了可读性,好理解。然后我们看下个语句:
mask = source[r].point(lambda i:i<100 and 255)
source【r】就是红色道的图片,point方法的参数是个函数或者说是个处理方法,简单理解就是,要对点进行的处理。我们来看这里的参数,是个lambda表达式,这个大家应该也不陌生,学基础python的时候不可能没用到过。我们看lambda表达式,表达式是i<100,也就是说满足表达式的点才返回。后面的and 255,整个的这个式子,官方文档确切的有说明,就是如果表达式为假,就返回0,只有为真的时候才返回255。那就好理解了吧,整个语句是对红色道的所有点进行处理,找到像素值小于100的点。看out:
out = source[g].point(lambda i:i*0.7)
这个应该就不难理解了,就是把绿色道的点的色素值调低百分之三十,这样理解,比如你某个点的g=100,上篇说道,r,g,b的取值是0-255,或者说是00-ff的。那我们这里处理完后就成了70了。之后的语句,paste,还记得吧。粘贴,看参数,很好理解,对绿色道进行处理,粘贴的是降低百分之30的out,粘贴区域region是红色道所有小于100的点的位置。这个语句执行完后,我们就得到了新的绿色道。能看懂吗,没看懂,在把paste的方法看一遍,再来理解下。
也就是说我们在红色道里找到的我们需要处理的点的位置,而想要在这些位置上的g(green)的值降低30百分点。就是这个意思。那现在的source的g色道,就不同于原来的了。
然后我要说的是merge,这里还是要理解成合并,和split是对立的,split是把一个个色道分离出来,可以单一处理,等你处理完,在把色道合并回去,就又成了彩色图了。嗯,就是这个道理。
因为那张图片大部分是红色,所以处理绿色效果很不明显:
def mergelijie(file):
im = Image.open(file)
r,g,b = im.split()
r = r.point(lambda i:i*0.1)
im = Image.merge(im.mode,(r,g,b))
im.save('popa.jpg')
那里懂了这里就很简明了吧,我把红色道单一拿出来,把所有的r值调到百分之十,看下效果:
r基本上就没了,是吧。(幻想有个虚无的对象再听我说话。)
三、Image.Enhance类
enhance增强的意思,有个方法,Contrast。翻译是对比,意译一下,就是对比度吧。这个方法的参数是要吞掉一个Image对象,然后用对象的方法进行处理:
def contrast(file):#30% more contrast
im = Image.open(file)
enh = ImageEnhance.Contrast(im)
enh.enhance(1.3).save('contrast.jpg')
对象的enhance方法对图片进行对比度增强的效果,参数是对比度的倍数,也就是说把对比度提高了百分之30。我们看下效果:
处理完后:
这个比那个DETAIL明显多了是吧。(血的颜色......黑红黑红......)
四、sequence图片序列
这个不是方法,我只想拿他说明功能,处理我们这种静态的图片,我们更喜欢玩的是动态图片,gif之类的。
这里科普下,动态图片本质上不是一张图,他是好几张图片连续播放,让你产生错觉,嗯,没听错,是错觉(视觉映像,专业名词),就是被你的眼睛欺骗之后的结果,可能也是种人类“低能”的表现之一,没办法短时间内处理那么多图片。这种现象被称作视觉暂留是吧,起了个高大上的名字。
我们说回来,当我们用open方法打开的是个.gif图片是,这时返回的对象就是个序列,懂我意思吧,就是一张一张的。那怎样去引用它呢。有点像python中文件对象,有两个方法:
seek(),tell()。
seek的参数就是调到指定位置,tell就是返回当前“指针”(我不知道这里说的准不准确哈)的位置。
那来看图片:
def sequences(file):
im = Image.open(file)
im.seek(1)#skip to the second frame
try:
while 1:
im.save(str(im.tell())+'.gif')
im.seek(im.tell()+1)
#do something
except EOFError:#the sequence ends
pass
这段程序就是把动态图一张张拿出来而已,这里说明下这个except,为何有except呢,因为我们的循环条件是1,也就是会一直循环,但是当到达最后一张图片的时候,再seek下一个就会出错了(因为莫得了嘛!),这就是except存在的原因。
我有这样一张图:
网上搞得,希望不会有什么问题哈。我们就拿这个图片做例子吧,按上面那段代码执行下,一张张保存下来:
就是酱紫的~~
五、ImageSequence的Iterator方法
这个没有什么特别的,sequence嘛,就是序列。iterator,迭代器。很显然,就是图片序列的迭代器,和(四)的整段代码的功能没太大区别。
参数要吞掉一个Image对象,返回对象的序列:
def iterator(file):
im = Image.open(file)
for frame in ImageSequence.Iterator(im):
print(type(frame))
这里小写了一个类,这样就可以循环遍历,不用像“四”那样,seek和telll了。
这次写到这里,后面如果还有需要写的东西再继续写。
(我也是处在学习过程中,我哪里写的、理解的不对的欢迎大牛评论提出,我再改。希望别吝惜赐教。)
后记:
没啥可写的,好水啊。