python手記(四):pillow(一) image類(序)
生活不易且無趣,一起找點樂子吧。歡迎評論,和文章無關的也可以。
上次的那篇文章裡,我們最後說到了,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圖片是,這時返回的物件就是個序列,懂我意思吧,就是一張一張的。那怎樣去引用它呢。有點像字串,有兩個方法:
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了。
這次寫到這裡,後面如果還有需要寫的東西再繼續寫。
(我也是處在學習過程中,我哪裡寫的、理解的不對的歡迎大牛評論提出,我再改。希望別吝惜賜教。)
後記:
沒啥可寫的,好水啊。