1. 程式人生 > >python手記(四):pillow(一) image類(序)

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了。

 

這次寫到這裡,後面如果還有需要寫的東西再繼續寫。

 

(我也是處在學習過程中,我哪裡寫的、理解的不對的歡迎大牛評論提出,我再改。希望別吝惜賜教。)

 

 

 

後記:

沒啥可寫的,好水啊。