Python用Pillow(PIL)進行簡單的圖像操作方法
顏色與RGBA值
計算機通常將圖像表示為RGB值,或者再加上alpha值(通透度,透明度),稱為RGBA值。在Pillow中,RGBA的值表示為由4個整數(shù)組成的元組,分別是R、G、B、A。整數(shù)的范圍0~255。RGB全0就可以表示黑色,全255代表黑色。可以猜測(255, 0, 0, 255)代表紅色,因為R分量最大,G、B分量為0,所以呈現(xiàn)出來是紅色。但是當alpha值為0時,無論是什么顏色,該顏色都不可見,可以理解為透明。
from PIL import ImageColor print(ImageColor.getcolor('red', 'RGBA')) # 也可以只以RBG的方式查看 print(ImageColor.getcolor('black', 'RGB'))
(255, 0, 0, 255) (0, 0, 0)
圖像的坐標表示
圖像中左上角是坐標原點(0, 0),這和平常數(shù)學里的坐標系不太一樣。這樣定義的坐標系意味著,X軸是從左到右增長的,而Y軸是從上到下增長。
在Pillow中如何使用上述定義的坐標系表示一塊矩形區(qū)域?許多函數(shù)或方法要求提供一個矩形元組參數(shù)。元組參數(shù)包含四個值,分別代表矩形四條邊的距離X軸或者Y軸的距離。順序是(左,頂,右,底)。右和底坐標稍微特殊,表示直到但不包括。可以理解為[左, 右)和[頂, 底)這樣左閉右開的區(qū)間。比如(3, 2, 8, 9)就表示了橫坐標范圍[3, 7];縱坐標范圍[2, 8]的矩形區(qū)域。
使用Pillow操作圖像
了解了一些基礎知識,可以上手了。首先從讀取圖片開始,很多圖像處理庫(如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) # 格式,以及格式的詳細描述 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返回一個元組,分別是寬和高。show()方法會調用系統(tǒng)默認圖像查看軟件,打開并顯示。im.format可查看圖像的格式。save()可保存處理后的圖片,如果未經處理,保存后的圖像占用的空間(字節(jié)數(shù))一般也與原圖像不一樣,可能經過了壓縮。
新建圖像
Pillow也可以新建空白圖像, 第一個參數(shù)是mode即顏色空間模式,第二個參數(shù)指定了圖像的分辨率(寬x高),第三個參數(shù)是顏色。
可以直接填入常用顏色的名稱。如'red'
也可以填入十六進制表示的顏色,如#FF0000表示紅色。
還能傳入元組,比如(255, 0, 0, 255)或者(255, 0, 0)表示紅色。
# 通常使用RGB模式就可以了 newIm= Image.new('RGB', (100, 100), 'red') newIm.save(r'C:\Users\Administrator\Desktop\1.jpg') # 也可以用RGBA模式,還有其他模式查文檔吧 blcakIm = Image.new('RGB',(200, 100), 'red') blcakIm.save(r'C:\Users\Administrator\Desktop\2.jpg') # 十六進制顏色 blcakIm = Image.new('RGBA',(200, 100), '#FF0000') blcakIm.save(r'C:\Users\Administrator\Desktop\3.jpg') # 傳入元組形式的RGBA值或者RGB值 # 在RGB模式下,第四個參數(shù)失效,默認255,在RGBA模式下,也可只傳入前三個值,A值默認255 blcakIm = Image.new('RGB',(200, 100), (255, 255, 0, 120)) blcakIm.save(r'C:\Users\Administrator\Desktop\4.jpg')
裁剪圖像
Image有個crop()方法接收一個矩形區(qū)域元組(上面有提到)。返回一個新的Image對象,是裁剪后的圖像,對原圖沒有影響。
im = Image.open(im_path) cropedIm = im.crop((700, 100, 1200, 1000)) cropedIm.save(r'C:\Users\Administrator\Desktop\cropped.jpg')
看下原圖和裁剪后的圖像。
復制與粘貼圖像到另一個圖像
Image的copy函數(shù)如其名會產生一個原圖像的副本,在這個副本上的任何操作不會影響到原圖像。paste()方法用于將一個圖像粘貼(覆蓋)在另一個圖像上面。誰調用它,他就在該Image對象上直接作修改。
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.jpg')
im.show()顯示圖像發(fā)現(xiàn)這時im(即原圖)已經被改變。
這如果之后還會用到原圖的信息,由于信息被改變就很麻煩。所以paste前最好使用copy()復制一個副本,在此副本操作,不會影響到原圖信息。雖然在程序里原圖信息已改變,但由于保存文件時用的其他文件名,相當于改變沒有生效,所以查看的時候原圖還是沒有改變的。
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.jpg')
這回再看原圖,沒有改變了。這就保證了之后再次使用im時,里面的信息還是原汁原味。來看個有趣的例子。
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.jpg')
以裁剪后的圖像寬度和高度為間隔,在循環(huán)內不斷粘貼在副本中,這有點像是在拍證件照。
調整圖像的大小
resize方法返回指定寬高度的新Image對象,接受一個含有寬高的元組作為參數(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.jpg')
兔子瘦了,可以看到resize不是等比例縮放的。
旋轉和翻轉圖像
rotate()返回旋轉后的新Image對象, 保持原圖像不變。逆時針旋轉。
im = Image.open(im_path) im.rotate(90).save(r'C:\Users\Administrator\Desktop\rotate90.jpg') im.rotate(270).save(r'C:\Users\Administrator\Desktop\rotate270.jpg') im.rotate(180).save(r'C:\Users\Administrator\Desktop\rotate180.jpg') im.rotate(20).save(r'C:\Users\Administrator\Desktop\rotate20.jpg') im.rotate(20, expand=True).save(r'C:\Users\Administrator\Desktop\rotate20_expand.jpg')
由上到下,分別是旋轉了90°,180°, 270°、普通的20°,加了參數(shù)expand=True旋轉的20°。expand放大了圖像尺寸(變成了2174x1672),使得邊角的圖像不被裁剪(四個角剛好貼著圖像邊緣)。再看旋轉90°、270°時候圖像被裁剪了,但是如下查看圖像的寬高,確是和原圖一樣,搞不懂。
im90 = Image.open(r'C:\Users\Administrator\Desktop\rotate90.jpg') im270 = Image.open(r'C:\Users\Administrator\Desktop\rotate270.jpg') # 寬高信息并沒有改變 print(im90.size, im270.size)
(1920, 1080) (1920, 1080)
圖像的鏡面翻轉。transpose()函數(shù)可以實現(xiàn),必須傳入Image.FLIP_LEFT_RIGHT或者Image.FLIP_TOP_BOTTOM,第一個是水平翻轉,第二個是垂直翻轉。
im = Image.open(im_path) im.transpose(Image.FLIP_LEFT_RIGHT).save(r'C:\Users\Administrator\Desktop\transepose_lr.jpg') im.transpose(Image.FLIP_TOP_BOTTOM).save(r'C:\Users\Administrator\Desktop\transepose_tb.jpg')
水平翻轉看不出來,原圖就是水平對稱的...
垂直翻轉就明顯了...
圖像過濾
Pillow使用ImageFilter可以簡單做到圖像的模糊、邊緣增強、銳利、平滑等常見操作。
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') # 邊緣增強 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') # 細節(jié) im.filter(ImageFilter.DETAIL).save(r'C:\Users\Administrator\Desktop\DETAIL.jpg')
另外,若是要進行圖案、文字的繪制,可使用ImageDraw。Pillow還有其他強大功能,就不一一列舉了。
其實,Pillow只是個基礎的圖像處理庫。若不深入圖像處理,已經夠用。專業(yè)人士使用opencv是更好地選擇。Python中使用import cv2開始使用吧!
以上這篇Python用Pillow(PIL)進行簡單的圖像操作方法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
