Python用Pillow(PIL)進(jìn)行簡(jiǎn)單的圖像操作

Python用Pillow(PIL)進(jìn)行簡(jiǎn)單的圖像操作

顏色與RGBA值

計(jì)算機(jī)通常將圖像表示為RGB值滞项,或者再加上alpha值(通透度,透明度),稱為RGBA值耸携。在Pillow中,RGBA的值表示為由4個(gè)整數(shù)組成的元組辕翰,分別是R夺衍、G、B喜命、A沟沙。整數(shù)的范圍0~255。RGB全0就可以表示黑色壁榕,全255代表黑色矛紫。可以猜測(cè)(255, 0, 0, 255)代表紅色牌里,因?yàn)镽分量最大颊咬,G、B分量為0牡辽,所以呈現(xiàn)出來(lái)是紅色喳篇。但是當(dāng)alpha值為0時(shí)陪每,無(wú)論是什么顏色臭挽,該顏色都不可見(jiàn),可以理解為透明翼雀。

from PIL import ImageColor
print(ImageColor.getcolor('red', 'RGBA'))
# 也可以只以RBG的方式查看
print(ImageColor.getcolor('black', 'RGB'))
(255, 0, 0, 255)
(0, 0, 0)

圖像的坐標(biāo)表示

圖像中左上角是坐標(biāo)原點(diǎn)(0, 0)奏黑,這和平常數(shù)學(xué)里的坐標(biāo)系不太一樣炊邦。這樣定義的坐標(biāo)系意味著编矾,X軸是從左到右增長(zhǎng)的,而Y軸是從上到下增長(zhǎng)铣耘。

在Pillow中如何使用上述定義的坐標(biāo)系表示一塊矩形區(qū)域洽沟?許多函數(shù)或方法要求提供一個(gè)矩形元組參數(shù)。元組參數(shù)包含四個(gè)值蜗细,分別代表矩形四條邊的距離X軸或者Y軸的距離裆操。順序是(左,頂炉媒,右踪区,底)。右和底坐標(biāo)稍微特殊吊骤,表示直到但不包括缎岗。可以理解為[左, 右)[頂白粉, 底)這樣左閉右開(kāi)的區(qū)間传泊。比如(3, 2, 8, 9)就表示了橫坐標(biāo)范圍[3, 7];縱坐標(biāo)范圍[2, 8]的矩形區(qū)域鸭巴。

使用Pillow操作圖像

了解了一些基礎(chǔ)知識(shí)眷细,可以上手了。首先從讀取圖片開(kāi)始鹃祖,很多圖像處理庫(kù)(如opencv)都以imread()讀取圖片溪椎。Pillow中使用open方法。

from PIL import Image

im_path = r'F:\Jupyter Notebook\csv_time_datetime_PIL\rabbit.jpg'
im = Image.open(im_path)
width, height = im.size
# 寬高
print(im.size, width, height)
# 格式恬口,以及格式的詳細(xì)描述
print(im.format, im.format_description)

im.save(r'C:\Users\Administrator\Desktop\rabbit_copy.jpg')
im.show()
(1920, 1080) 1920 1080
JPEG JPEG (ISO 10918)

im.size返回一個(gè)元組校读,分別是寬和高。show()方法會(huì)調(diào)用系統(tǒng)默認(rèn)圖像查看軟件祖能,打開(kāi)并顯示歉秫。im.format可查看圖像的格式。save()可保存處理后的圖片养铸,如果未經(jīng)處理雁芙,保存后的圖像占用的空間(字節(jié)數(shù))一般也與原圖像不一樣,可能經(jīng)過(guò)了壓縮揭厚。

新建圖像

Pillow也可以新建空白圖像, 第一個(gè)參數(shù)是mode即顏色空間模式却特,第二個(gè)參數(shù)指定了圖像的分辨率(寬x高)扶供,第三個(gè)參數(shù)是顏色筛圆。

  • 可以直接填入常用顏色的名稱。如'red'
  • 也可以填入十六進(jìn)制表示的顏色椿浓,如#FF0000表示紅色太援。
  • 還能傳入元組闽晦,比如(255, 0, 0, 255)或者(255, 0提岔, 0)表示紅色仙蛉。
# 通常使用RGB模式就可以了
newIm= Image.new('RGB', (100, 100), 'red')
newIm.save(r'C:\Users\Administrator\Desktop\1.png')

# 也可以用RGBA模式,還有其他模式查文檔吧
blcakIm = Image.new('RGB',(200, 100), 'red')
blcakIm.save(r'C:\Users\Administrator\Desktop\2.png')
# 十六進(jìn)制顏色
blcakIm = Image.new('RGBA',(200, 100), '#FF0000')
blcakIm.save(r'C:\Users\Administrator\Desktop\3.png')
# 傳入元組形式的RGBA值或者RGB值
# 在RGB模式下碱蒙,第四個(gè)參數(shù)失效荠瘪,默認(rèn)255,在RGBA模式下赛惩,也可只傳入前三個(gè)值哀墓,A值默認(rèn)255
blcakIm = Image.new('RGB',(200, 100), (255, 255, 0, 120))
blcakIm.save(r'C:\Users\Administrator\Desktop\4.png')

裁剪圖像

Image有個(gè)crop()方法接收一個(gè)矩形區(qū)域元組(上面有提到)。返回一個(gè)新的Image對(duì)象喷兼,是裁剪后的圖像篮绰,對(duì)原圖沒(méi)有影響。

im = Image.open(im_path)
cropedIm = im.crop((700, 100, 1200, 1000))
cropedIm.save(r'C:\Users\Administrator\Desktop\cropped.png')

看下原圖和裁剪后的圖像季惯。

原圖
裁剪后

復(fù)制與粘貼圖像到另一個(gè)圖像

Imagecopy函數(shù)如其名會(huì)產(chǎn)生一個(gè)原圖像的副本吠各,在這個(gè)副本上的任何操作不會(huì)影響到原圖像。paste()方法用于將一個(gè)圖像粘貼(覆蓋)在另一個(gè)圖像上面勉抓。誰(shuí)調(diào)用它贾漏,他就在該Image對(duì)象上直接作修改。

im = Image.open(im_path)
cropedIm = im.crop((700, 100, 1200, 1000))
im.paste(cropedIm, (0, 0))
im.show()
im.save(r'C:\Users\Administrator\Desktop\paste.png')

im.show()顯示圖像發(fā)現(xiàn)這時(shí)im(即原圖)已經(jīng)被改變琳状。

這如果之后還會(huì)用到原圖的信息磕瓷,由于信息被改變就很麻煩。所以paste前最好使用copy()復(fù)制一個(gè)副本念逞,在此副本操作困食,不會(huì)影響到原圖信息。雖然在程序里原圖信息已改變翎承,但由于保存文件時(shí)用的其他文件名硕盹,相當(dāng)于改變沒(méi)有生效,所以查看的時(shí)候原圖還是沒(méi)有改變的叨咖。

im = Image.open(im_path)
cropedIm = im.crop((700, 100, 1200, 1000))
copyIm = im.copy()
copyIm.paste(cropedIm, (0, 0))
im.show()
copyIm.save(r'C:\Users\Administrator\Desktop\paste.png')

這回再看原圖瘩例,沒(méi)有改變了。這就保證了之后再次使用im時(shí)甸各,里面的信息還是原汁原味垛贤。來(lái)看個(gè)有趣的例子。

im = Image.open(im_path)
cropedIm = im.crop((700, 100, 1200, 1000))

crop_width, crop_height = cropedIm.size
width, height = im.size

copyIm = im.copy()
for left in range(0, width, crop_width):
    for top in range(0, height, crop_height):
        copyIm.paste(cropedIm, (left, top))

copyIm.save(r'C:\Users\Administrator\Desktop\dupli-rabbit.png')

以裁剪后的圖像寬度和高度為間隔趣倾,在循環(huán)內(nèi)不斷粘貼在副本中聘惦,這有點(diǎn)像是在拍證件照。

調(diào)整圖像的大小

resize方法返回指定寬高度的新Image對(duì)象儒恋,接受一個(gè)含有寬高的元組作為參數(shù)善绎。寬高的值得是整數(shù)黔漂。

im = Image.open(im_path)
width, height = im.size
resizedIm = im.resize((width, height+(1920-1080)))
resizedIm.save(r'C:\Users\Administrator\Desktop\resize.png')

兔子瘦了,可以看到resize不是等比例縮放的禀酱。

旋轉(zhuǎn)和翻轉(zhuǎn)圖像

rotate()返回旋轉(zhuǎn)后的新Image對(duì)象, 保持原圖像不變炬守。逆時(shí)針旋轉(zhuǎn)。

im = Image.open(im_path)
im.rotate(90).save(r'C:\Users\Administrator\Desktop\rotate90.png')
im.rotate(270).save(r'C:\Users\Administrator\Desktop\rotate270.png')
im.rotate(180).save(r'C:\Users\Administrator\Desktop\rotate180.png')
im.rotate(20).save(r'C:\Users\Administrator\Desktop\rotate20.png')
im.rotate(20, expand=True).save(r'C:\Users\Administrator\Desktop\rotate20_expand.png')
90
180
270
20

由上到下剂跟,分別是旋轉(zhuǎn)了90°减途,180°, 270°曹洽、普通的20°观蜗,加了參數(shù)expand=True旋轉(zhuǎn)的20°。expand放大了圖像尺寸(變成了2174x1672)衣洁,使得邊角的圖像不被裁剪(四個(gè)角剛好貼著圖像邊緣)墓捻。再看旋轉(zhuǎn)90°、270°時(shí)候圖像被裁剪了坊夫,但是如下查看圖像的寬高砖第,確是和原圖一樣,搞不懂环凿。

im90 = Image.open(r'C:\Users\Administrator\Desktop\rotate90.png')
im270 = Image.open(r'C:\Users\Administrator\Desktop\rotate270.png')
# 寬高信息并沒(méi)有改變
print(im90.size, im270.size)
(1920, 1080) (1920, 1080)

圖像的鏡面翻轉(zhuǎn)梧兼。transpose()函數(shù)可以實(shí)現(xiàn),必須傳入Image.FLIP_LEFT_RIGHT或者Image.FLIP_TOP_BOTTOM智听,第一個(gè)是水平翻轉(zhuǎn)羽杰,第二個(gè)是垂直翻轉(zhuǎn)。

im = Image.open(im_path)
im.transpose(Image.FLIP_LEFT_RIGHT).save(r'C:\Users\Administrator\Desktop\transepose_lr.png')
im.transpose(Image.FLIP_TOP_BOTTOM).save(r'C:\Users\Administrator\Desktop\transepose_tb.png')
水平翻轉(zhuǎn)

水平翻轉(zhuǎn)看不出來(lái)到推,原圖就是水平對(duì)稱的...

垂直翻轉(zhuǎn)

垂直翻轉(zhuǎn)就明顯了...

圖像過(guò)濾

Pillow使用ImageFilter可以簡(jiǎn)單做到圖像的模糊考赛、邊緣增強(qiáng)、銳利莉测、平滑等常見(jiàn)操作颜骤。

from PIL import Image, ImageFilter

im = Image.open(im_path)
# 高斯模糊
im.filter(ImageFilter.GaussianBlur).save(r'C:\Users\Administrator\Desktop\GaussianBlur.jpg')
# 普通模糊
im.filter(ImageFilter.BLUR).save(r'C:\Users\Administrator\Desktop\BLUR.jpg')
# 邊緣增強(qiáng)
im.filter(ImageFilter.EDGE_ENHANCE).save(r'C:\Users\Administrator\Desktop\EDGE_ENHANCE.jpg')
# 找到邊緣
im.filter(ImageFilter.FIND_EDGES).save(r'C:\Users\Administrator\Desktop\FIND_EDGES.jpg')
# 浮雕
im.filter(ImageFilter.EMBOSS).save(r'C:\Users\Administrator\Desktop\EMBOSS.jpg')
# 輪廓
im.filter(ImageFilter.CONTOUR).save(r'C:\Users\Administrator\Desktop\CONTOUR.jpg')
# 銳化
im.filter(ImageFilter.SHARPEN).save(r'C:\Users\Administrator\Desktop\SHARPEN.jpg')
# 平滑
im.filter(ImageFilter.SMOOTH).save(r'C:\Users\Administrator\Desktop\SMOOTH.jpg')
# 細(xì)節(jié)
im.filter(ImageFilter.DETAIL).save(r'C:\Users\Administrator\Desktop\DETAIL.jpg')

另外,若是要進(jìn)行圖案捣卤、文字的繪制忍抽,可使用ImageDraw。Pillow還有其他強(qiáng)大功能董朝,就不一一列舉了鸠项。

其實(shí),Pillow只是個(gè)基礎(chǔ)的圖像處理庫(kù)子姜。若不深入圖像處理祟绊,已經(jīng)夠用。專業(yè)人士使用opencv是更好地選擇。Python中使用import cv2開(kāi)始使用吧久免!


by @sunhaiyu

2017.7.6

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市扭弧,隨后出現(xiàn)的幾起案子阎姥,更是在濱河造成了極大的恐慌,老刑警劉巖鸽捻,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呼巴,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡御蒲,警方通過(guò)查閱死者的電腦和手機(jī)衣赶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)厚满,“玉大人府瞄,你說(shuō)我怎么就攤上這事〉夤浚” “怎么了遵馆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)丰榴。 經(jīng)常有香客問(wèn)我货邓,道長(zhǎng),這世上最難降的妖魔是什么四濒? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任换况,我火速辦了婚禮,結(jié)果婚禮上盗蟆,老公的妹妹穿的比我還像新娘戈二。我一直安慰自己,他們只是感情好喳资,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布挽拂。 她就那樣靜靜地躺著,像睡著了一般骨饿。 火紅的嫁衣襯著肌膚如雪亏栈。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,624評(píng)論 1 305
  • 那天宏赘,我揣著相機(jī)與錄音绒北,去河邊找鬼。 笑死察署,一個(gè)胖子當(dāng)著我的面吹牛闷游,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼脐往,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼休吠!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起业簿,我...
    開(kāi)封第一講書(shū)人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤瘤礁,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后梅尤,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體柜思,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年巷燥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赡盘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缰揪,死狀恐怖陨享,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情钝腺,我是刑警寧澤霉咨,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站拍屑,受9級(jí)特大地震影響途戒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜僵驰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一喷斋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蒜茴,春花似錦星爪、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至诺核,卻和暖如春抄肖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背窖杀。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工漓摩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人入客。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓管毙,卻偏偏與公主長(zhǎng)得像腿椎,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子夭咬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容