Python圖像處理庫(kù)Pillow的簡(jiǎn)單實(shí)現(xiàn)
Pillow 是Python Imaging Library 的簡(jiǎn)稱,是Python 語(yǔ)言中最為常用的圖像處理庫(kù)。Pillow 庫(kù)提供了對(duì) Python3 的支持,為 Python3 解釋器提供了圖像處理的功能。通過(guò)使用 Pillow 庫(kù), 可以方便地使用 Python 程序?qū)D片進(jìn)行處理,例如常見(jiàn)的尺寸、格式、色彩、旋轉(zhuǎn)等處理。
Pillow 庫(kù)的安裝
Pillow 庫(kù)是 Python 開發(fā)者最為常見(jiàn)的圖像處理庫(kù),它提供了廣泛的文件格式支持、強(qiáng)大的圖像處理能力,主要包括圖像存儲(chǔ)、圖像顯示、格式轉(zhuǎn)換以及基本的圖像處理操作等。 安裝 Pillow 庫(kù)的方法與安裝 Python 其他第三方庫(kù)的方法相同,也可以到 Python 官方網(wǎng)站下載 Pillow 庫(kù)的壓縮包。
pip 安裝 pillow,執(zhí)行如下命令:
pip install pillow
圖象處理基本知識(shí)
圖像的RGB 色彩模式
RGB 三個(gè)顏色通道的變化和疊加得到各種顏色,其中
- R 紅色,取值范圍,0-255
- G 綠色,取值范圍,0-255
- B 藍(lán)色,取值范圍,0-255
比如,我們常見(jiàn)的黃色就是由紅色和綠色疊加而來(lái)。
- 紅色的 RGB 表示(255,0,0)
- 綠色的 RGB 表示(0,255,0)
- 藍(lán)色的 RGB 表示(0,0,255)
- 黃色的 RGB 表示(255,255,0)
像素陣列
數(shù)字圖像可以看成一個(gè)整數(shù)陣列,陣列中的元素稱為像素(Pixel),見(jiàn)下圖的數(shù)字陣列

每個(gè)點(diǎn)代表 1 個(gè)像素(Pixel),一個(gè)點(diǎn)包含 RGB 三種顏色。也就是 1 個(gè)像素包含 3 個(gè)字節(jié)的信息:(R,G,B)。假如這個(gè)像素是紅色,則信息是:(255,0,0)。那么,理論上我們只要操作每個(gè)點(diǎn)上的這三個(gè)數(shù)字,就能實(shí)現(xiàn)任何的圖形。一幅圖像上的所有像素點(diǎn)的信息就完全可以采用矩陣來(lái)表示,通過(guò)矩陣的運(yùn)算實(shí)現(xiàn)更加復(fù)雜的操作。
Image 模塊
打開和新建
在 Pillow 庫(kù)中,通過(guò)使用 Image 模塊,可以從文件中加載圖像,或者處理其他圖像, 或者從 scratch 中創(chuàng)建圖像。在對(duì)圖像進(jìn)行處理時(shí),首先需要打開要處理的圖片。在 Image 模塊中使用函數(shù) open()打開一副圖片,執(zhí)行后返回 Image 類的實(shí)例。當(dāng)文件不存在時(shí),會(huì)引發(fā) IOError 錯(cuò)誤。使用函數(shù) open()語(yǔ)法格式如下所示。
open(fp,mode)
- fp:指打開文件的路徑。
- mode:可選參數(shù),表示打開文件的方式,通常使用默認(rèn)值 r。在 Image 模塊中,可以使用函數(shù) new()新建圖像。具體語(yǔ)法格式如下所示:
new(mode,size,color=0)
(1) mode:圖片模式,具體取值如下表
(2) size:表示圖片尺寸,是使用寬和高兩個(gè)元素構(gòu)成的元組
(3) color:默認(rèn)顏色(黑色)
Pillow 庫(kù)支持的常用圖片模式信息
| mode(模式) | bands(通道) | 說(shuō)明 |
|---|---|---|
| “1” | 1 | 數(shù)字 1,表示黑白二值圖像,每個(gè)像素用 0 或者 1 共 1 位二進(jìn)制代碼表示 |
| “L” | 1 | 灰度圖,每個(gè)像素用 8 位二進(jìn)制代碼表示 |
| “P” | 1 | 索引圖,每個(gè)像素用 8 位二進(jìn)制代碼表示 |
| “RGB” | 3 | 24 位真彩圖,每個(gè)像素用 3 個(gè)字節(jié)的二進(jìn)制代碼表示 |
| “RGBA” | 4 | “RGB”+透明通道表示,每個(gè)像素用 4 字節(jié)的二進(jìn)制代碼表示 |
| “CMYK” | 4 | 印刷模式圖像,每個(gè)像素用 4 字節(jié)的二進(jìn)制代碼表示 |
| “YCbCr” | 3 | 彩色視頻顏色隔離模式,每個(gè)像素用 3 個(gè)字節(jié)的二進(jìn)制代碼表示 |
| “LAB” | 3 | lab 顏色空間,每個(gè)像素用 3 字節(jié)的二進(jìn)制代碼表示 |
| “HSV” | 3 | 每個(gè)像素用 3 字節(jié)的二進(jìn)制代碼表示 |
| “I” | 1 | 使用整數(shù)形式表示像素,每個(gè)像素用 4 字節(jié)的二進(jìn)制代碼表示 |
| “F” | 1 | 使用浮點(diǎn)數(shù)形式表示像素,每個(gè)像素用 4 字節(jié)的二進(jìn)制代碼表示 |
【示例】使用 Image 打開一副圖片
#導(dǎo)入 Image 模塊
from PIL import Image
#打開圖片
im=Image.open('bjsxt.png')
#顯示圖片
im.show()
#查看圖片的信息
print('圖像格式:',im.format)
print('圖像大小,格式是(寬度,高度):',im.size) print('圖像寬度:',im.width,'圖像高度:',im.height)運(yùn)行結(jié)果如下圖:

混合
透明度混合處理
在 Pillow 庫(kù)的 Image 模塊中,可以使用函數(shù) blend()實(shí)現(xiàn)透明度混合處理。具體語(yǔ)法格式如下所示:
blend(im1,im2,alpha)
其中 im1、im2 指參與混合的圖片 1 和圖片 2,alpha 指混合透明度,取值是 0-1。通過(guò)使用函數(shù) blend(),可以將 im1 和 im2 這兩幅圖片(尺寸相同)以一定的透明度進(jìn)行混合。具體混合過(guò)程如下:
(im1*(1-alpha)+im2*alpha)
當(dāng)混合透明度為 0 時(shí),顯示 im1 原圖。當(dāng)混合透明度 alpha 取值為 1 時(shí),顯示 im2原圖片。
【示例】透明度混合圖片
from PIL import Image
img1=Image.open('bjsxt.jpg').convert(mode="RGB")
img2=Image.new("RGB",img1.size,"red")
# #混合兩幅圖
Image.blend(img1,img2,alpha=0.5).show()執(zhí)行結(jié)果如下圖:


遮罩混合處理
在 Pillow 庫(kù)中 Image 模塊中,可以使用函數(shù) composite()實(shí)現(xiàn)遮罩混合處理。具體語(yǔ)法格式如下所示:
composite(im1,im2,mask)
其中 im1 和 im2 表示混合處理的圖片 1 和圖片 2.mask 也是一個(gè)圖像,mode 可以為“1”, “L”, or “RGBA”,并且大小要和 im1、im2 一樣。
函數(shù) composite()的功能是使用 mask 來(lái)混合圖片 im1 和 im2,并且要求 mask、im1 和 im2 三幅圖片的尺寸相同。下面的實(shí)例代碼演示了使用 Image 模塊實(shí)現(xiàn)圖片遮罩混合處理的過(guò)程。
【示例】遮罩混合圖片
from PIL import Image
img1=Image.open('img1.jpg')
img2=Image.open('img2.jpg')
img2=img2.resize(img1.size)
r,g,b=img2.split()
Image.composite(img2,img1,b).show()執(zhí)行結(jié)果如下圖:



復(fù)制和縮放
復(fù)制圖像
在 Pillow 庫(kù)的 Image 模塊中,可以使用函數(shù) Image.copy()復(fù)制指定的圖片,這可以用于在處理或粘貼時(shí)需要持有源圖片。
縮放像素
在 Pillow 庫(kù)的 Image 模塊中,可以使用函數(shù) eval()實(shí)現(xiàn)像素縮放處理,能夠使用函數(shù) fun()計(jì)算輸入圖片的每個(gè)像素并返回。使用函數(shù) eval()語(yǔ)法格式如下:
eval(image,fun)
其中 image 表示輸入的圖片,fun 表示給輸入圖片的每個(gè)像素應(yīng)用此函數(shù),fun()函數(shù)只允許接收一個(gè)整型參數(shù)。如果一個(gè)圖片含有多個(gè)通道,則每個(gè)通道都會(huì)應(yīng)用這個(gè)函數(shù)。
【示例】縮放指定的圖片,實(shí)現(xiàn)圖像每個(gè)像素值×2
from PIL import Image
img=Image.open('img2.jpg')
Image.eval(img,lambda i:i*2).show()縮放圖像
在 Pillow 庫(kù)的 Image 模塊中,可以使用函數(shù) thumbnail()原生地縮放指定的圖像 。具體語(yǔ)法格式如下:
Image.thmbnail(size,resample=3)
【示例】縮放成指定的大小
from PIL import Image
img=Image.open('img2.jpg')
imgb=img.copy()
#縮放為指定大小(220,168)
imgb.thumbnail((220,168))
imgb.show()粘貼和裁剪
粘貼
在 Pillow 庫(kù)的 Image 模塊中,函數(shù) paste()的功能是粘貼源圖像或像素至該圖像中。具體語(yǔ)法格式如下:
Image.paste(im,box=None,mask=None)
其中 im 是源圖或像素值;box 是粘貼的區(qū)域;mask 是遮罩。參數(shù) box 可以分為以下 3 中情況。
(x1,y1):將源圖像左上角對(duì)齊(x1,y1)點(diǎn),其余超出被粘貼圖像的區(qū)域被拋棄。(x1,y1,x2,y2):源圖像與此區(qū)域必須一致。None:源圖像與被粘貼的圖像大小必須一致。 裁剪圖像
在 Pillow 庫(kù)的 Image 模塊中,函數(shù) crop()的功能是剪切圖片中 box 所指定的區(qū)域, 具體語(yǔ)法如下:
Image.crop(box=None)
參數(shù) box 是一個(gè)四元組,分別定義了剪切區(qū)域的左、上、右、下 4 個(gè)坐標(biāo)。
【示例】對(duì)指定圖片剪切和粘貼操作
from PIL import Image
img=Image.open('bjsxt.png')
# 復(fù)制圖片
imgb=img.copy()
imgc=img.copy()
# 剪切圖片
region=imgb.crop((5,5,120,120))
#粘貼圖片
imgc.paste(region,(30,30))
imgc.show()圖像旋轉(zhuǎn)
在 Pillow 庫(kù)的 Image 模塊中,函數(shù) rotate()的功能返回此圖像的副本,圍繞其中心逆時(shí)針旋轉(zhuǎn)給定的度數(shù)。具體語(yǔ)法格式如下:
Image.rotate(angle,resample = 0,expand = 0,center = None,translate = None,fillcolor= None )
【示例】函數(shù) rotate()實(shí)現(xiàn)圖像旋轉(zhuǎn)
from PIL import Image
img=Image.open('bjsxt.png')
img.rotate(90).show()格式轉(zhuǎn)換
covert()
在 Pillow 庫(kù)的 Image 模塊中,函數(shù) convert()的功能是返回模式轉(zhuǎn)換后的圖像實(shí)例。具體轉(zhuǎn)換的語(yǔ)法格式如下:
Image.convert(mode=None,matrix=None,dither=None,palette=0,colors=256)
其中 mode:轉(zhuǎn)換文件的模式,默契支持的模式有“L”、“RGB”“CMYK”;matrix:轉(zhuǎn)使用的矩陣;dither:取值為 None 切轉(zhuǎn)為黑白圖時(shí)非 0(1-255)像素均為白,也可以設(shè)置此參數(shù)為 FLOYDSTEINBERG。
transpose()
在 Pillow 庫(kù)的 Image 模塊中,函數(shù) transpose()函數(shù)功能是實(shí)現(xiàn)圖像格式的轉(zhuǎn)換。具體語(yǔ)法格式如下:
Image.transpose(method)
轉(zhuǎn)換圖像后,返回轉(zhuǎn)換后的圖像,“method”的取值有以下幾個(gè)。
- PIL.Image.FLIP_LEFT_RIGHT:左右鏡像
- PIL.Image.FLIP_TOP_BOTTOM :上下鏡像
- PIL.Image.ROTATE_90:旋轉(zhuǎn) 90
- PIL.Image.ROTATE_180:旋轉(zhuǎn) 180
- PIL.Image.ROTATE_270:旋轉(zhuǎn) 270
- PIL.Image.TRANSPOSE :顛倒順序
【示例】對(duì)指定圖片進(jìn)行轉(zhuǎn)換操作
from PIL import Image
#打開指定的圖片
img1=Image.open('bjsxt.png')
img2=img1.copy()
#convert()
img_convert=img2.convert('CMYK')
# img_convert.show()
#transpose()
img_transpose=img2.transpose(Image.ROTATE_90)
img_transpose.show()分離和合并
分離
在 Pillow 庫(kù)的 Image 模塊中,使用函數(shù) split()可以將圖片分割為多個(gè)通道列表。使用函數(shù) split()的語(yǔ)法格式如下所示:
Image.split()
合并
在 Pillow 庫(kù)的 Image 模塊中,使用函數(shù) merge()可以將一個(gè)通道的圖像合并到更多通道圖像中。使用函數(shù) merge()的語(yǔ)法格式如下所示:
Image.merge(mode,bands)
其中 mode 指輸出圖像的模式,bands 波段通道,一個(gè)序列包含單個(gè)帶圖通道。
【示例】對(duì)指定圖片進(jìn)行合并和分離操作
from PIL import Image
img1=Image.open('blend1.jpg')
img2=Image.open('blend2.jpg')
img2=img2.resize(img1.size)
r1,g1,b1= img1.split()
r2,g2,b2= img2.split()
tmp=[r1,g2,b1]
img = Image.merge("RGB",tmp)
img.show()濾鏡
在 Pillow 庫(kù)中的 Image 模塊中,使用函數(shù) filter()可以對(duì)指定的圖片使用濾鏡效果,在Pillow 庫(kù)中可以用的濾鏡保存在 ImageFilter 模塊中。使用函數(shù) filter()的語(yǔ)法格式如下所示:
Image.filter(filter)
通過(guò)函數(shù) filter(),可以使用給定的濾鏡過(guò)慮指定的圖像,參數(shù)“filter”表示濾鏡內(nèi)核。
【示例】對(duì)指定圖片實(shí)現(xiàn)濾鏡模糊操作
from PIL import Image,ImageFilter
#使用函數(shù) filter()實(shí)現(xiàn)濾鏡效果
img=Image.open('bjsxt.png')
b=img.filter(ImageFilter.GaussianBlur)
b.show()其他內(nèi)置函數(shù)
在 Pillow 庫(kù)的 Image 模塊中,還有很多其他重要的內(nèi)置函數(shù)和屬性。常用的屬性:
- Image.format:源圖像格式
- Image.mode:圖像模式字符串
- Image.size:圖像尺寸
在 Pillow 庫(kù)的 Image 模塊中,其他常用的內(nèi)置函數(shù)如下所示:
- Image.getbands():獲取圖像每個(gè)通道的名稱列表,例如 RGB 圖像返回[‘R’,’G’,’B’]。
- Image.getextrema():獲取圖像最大、最小像素的值。
- Image.getpixel(xy):獲取像素點(diǎn)值。
- Image.histogram(mask=None,extrema=None):獲取圖像直方圖,返回像素計(jì)數(shù)的列表。
- Image.point(function):使用函數(shù)修改圖像的每個(gè)像素。
- Image.putalpha(alpha):添加或替換圖像的 alpha 層。
- Image.save(fp,format=None,**params):保存圖片。
- Image.show(title=None,command=None):顯示圖片。
- Image.transform(size,method,data=None,resample=0,fill=1):變換圖像。
- Image.verify():校驗(yàn)文件是否損壞。
- Image.close():關(guān)閉文件。
ImageFilter 模塊
內(nèi)置模塊 ImageFilter 實(shí)現(xiàn)了濾鏡功能,可以用來(lái)創(chuàng)建圖像特效,或以此效果作為媒介實(shí)現(xiàn)進(jìn)一步處理。
在模塊 ImageFilter 中,提供了一些預(yù)定義的濾鏡和自定義濾鏡函數(shù)。其中最為常用的預(yù)定義濾鏡如下所示:
- BLUE:模糊
- CONTOUR:輪廓
- DETAIL:詳情
- EDGE_ENHANCE:邊緣增強(qiáng)
- EDGE_ENHANCE_MORE:邊緣更多增強(qiáng)
- EMBOSS:浮雕
- FIND_EDGES:尋找邊緣
- SHARPEN:銳化
- SMOOTH:平滑
在模塊 ImageFilter 中,常用的自定義濾鏡函數(shù)如下所示:
| 函數(shù)名 | 功能 |
|---|---|
| ImageFilter.GaussianBlur(radius = 2 ) | 高斯模糊 |
| ImageFilter.UnsharpMask(radius = 2,percent = 150,threshold= 3 ) | 不清晰的掩模濾鏡 |
| ImageFilter.MinFilter(size = 3 ) | 最小值濾波 |
| ImageFilter.MedianFilter(size = 3 ) | 中值濾波 |
| ImageFilter.ModeFilter(size = 3 ) | 模式濾波 |
【示例】使用 ImageFilter 對(duì)指定圖片實(shí)現(xiàn)濾鏡特效
from PIL import Image,ImageFilter
#打開圖片
imga=Image.open('img2.jpg')
w,h=imga.size
#創(chuàng)建圖像區(qū)域
img_output=Image.new('RGB',(2*w,h))
#將創(chuàng)建的部分粘貼圖片
img_output.paste(imga,(0,0))
#創(chuàng)建列表存儲(chǔ)濾鏡fltrs=[]
fltrs.append(ImageFilter.EDGE_ENHANCE)# 邊緣強(qiáng)化濾鏡
fltrs.append(ImageFilter.FIND_EDGES) # 查找邊緣濾鏡
fltrs.append(ImageFilter.GaussianBlur)#高斯模糊濾鏡
for fltr in fltrs:
r=imga.filter(fltr)
img_output.paste(r,(w,0))
img_output.show()ImageChops 模塊
在 Pillow 庫(kù)的內(nèi)置模塊 ImageChops 中包含了多個(gè)用于實(shí)現(xiàn)圖片合成的函數(shù)。這些合成功能是通過(guò)計(jì)算通道中像素值的方式來(lái)實(shí)現(xiàn)的。其主要用于制作特效、合成圖片等操作。常用的內(nèi)置函數(shù)如下所示:
1.相加函數(shù) add(),功能是對(duì)兩張圖片進(jìn)行算術(shù)加法運(yùn)算。具體語(yǔ)法如下所示:
ImageChops.add(image1,image2,scale = 1.0,offset = 0 )
在合成后圖像中的每個(gè)像素值,是兩幅圖像對(duì)應(yīng)像素值依據(jù)下面的公式進(jìn)行計(jì)算得到的。
out = ((image1 + image2) / scale + offset)
【示例】使用 add 圖片合成
from PIL import Image
from PIL import ImageChops
#打開圖片
imga=Image.open('blend1.jpg')
imgb=Image.open('blend2.jpg')
#對(duì)兩張圖片進(jìn)行算術(shù)加法運(yùn)算
ImageChops.add(imga,imgb,1,0).show()out = ((image1 + image2) / scale + offset)
2.減法函數(shù) subtract(),功能是對(duì)兩張圖片進(jìn)行算術(shù)減法運(yùn)算。具體語(yǔ)法如下所示
ImageChops.subtract(image1,image2,scale = 1.0,offset = 0 )
在合成后圖像中的每個(gè)像素值,是兩幅圖像對(duì)應(yīng)像素值依據(jù)下面的公式進(jìn)行得到的。
out = ((image1 - image2) / scale + offset)
【示例】使用 subtract()圖片合成
from PIL import Image
from PIL import ImageChops
#打開圖片
imga=Image.open('blend1.jpg')
imgb=Image.open('blend2.jpg')
#對(duì)兩張圖片進(jìn)行減法運(yùn)算
ImageChops.subtract(imga,imgb,1,0).show()3.變暗函數(shù) darker(),功能是比較兩個(gè)圖片的像素,取兩張圖片中對(duì)應(yīng)像素的較小值,所以合成時(shí)兩幅圖像中對(duì)應(yīng)位置的暗部分得到保留,而去除亮部分。具體語(yǔ)法如下所示:
ImageChops.darker(image1,image2 )
像素的計(jì)算公式如下所示:
out = min(image1, image2)
【示例】使用 darker()圖片合成
from PIL import Image
from PIL import ImageChops
#打開圖片
imga=Image.open('blend1.jpg')
imgb=Image.open('blend2.jpg')
#使用變暗函數(shù) darker()
ImageChops.darker(imga,imgb).show()4.變亮函數(shù) lighter(),與變暗函數(shù) darker()相反,功能是比較兩個(gè)圖片(逐像素比較), 返回一幅新的圖片,這幅新的圖片是將兩張圖片中較亮的部分疊加得到的。也就是說(shuō),在某 一點(diǎn)上,兩張圖中哪個(gè)的值大(亮)則取之。具體語(yǔ)法如下所示:
ImageChops.lighter(image1,image2 )
函數(shù) lighter()與函數(shù) darker()的功能相反,計(jì)算后得到的圖像是兩幅圖像對(duì)應(yīng)位置的亮部分。像素的計(jì)算公式如下所示:
out = max(image1, image2)
【示例】使用 lighter()圖片合成
from PIL import Image
from PIL import ImageChops
#打開圖片
imga=Image.open('blend1.jpg')
imgb=Image.open('blend2.jpg')
#使用變亮函數(shù) lighter()
ImageChops.lighter(imga,imgb).show()5.疊加函數(shù) multiply(),功能是將兩張圖片互相疊加。如果用純黑色與某圖片進(jìn)行疊加操作,就會(huì)得到一幅純黑色的圖片。如果用純白色與圖片作疊加,則圖片不受影響。具體語(yǔ)法
ImageChops.multiply(image1,image2 )
如下所示:
合成的圖像的效果類似兩張圖片在透明的描圖紙上疊放在一起觀看的效果。其對(duì)應(yīng)像素的計(jì) 算公式如下所示:
out = image1 * image2 / MAX
【示例】使用 multiply()圖片合成
from PIL import Image
from PIL import ImageChops
#打開圖片
imga=Image.open('blend1.jpg')
imgb=Image.open('blend2.jpg')
#將兩張圖片相互疊加
ImageChops.multiply(imga,imgb).show()6.屏幕函數(shù) screen(),功能是先反色后疊加,實(shí)現(xiàn)合成圖像的效果,就像將兩張幻燈片用兩臺(tái)投影機(jī)同時(shí)投影到一個(gè)屏幕上的效果。具體語(yǔ)法如下所示:
ImageChops.screen(image1,image2 )
其對(duì)應(yīng)像素的計(jì)算公式如下所示:
out = MAX - ((MAX - image1) * (MAX - image2) / MAX)
【示例】使用 screen()圖片合成
from PIL import Image
from PIL import ImageChops
#打開圖片
imga=Image.open('blend1.jpg')
imgb=Image.open('blend2.jpg')
#實(shí)現(xiàn)反色后疊加
# ImageChops.screen(imga,imgb).show()7.反色函數(shù) invert(),類似于集合操作中的求補(bǔ)集,最大值為 Max,每個(gè)像素做減法,取出反色。在反色時(shí)將用 255 減去一幅圖像的每個(gè)像素值,從而得到原來(lái)圖像的反相。也就是說(shuō),其表現(xiàn)為“底片”性質(zhì)的圖像。具體語(yǔ)法如下所示:
ImageChops.invert(image)
其對(duì)應(yīng)像素的計(jì)算公式如下所示:
out = MAX - image
【示例】使用 invert()圖片合成
from PIL import Image
from PIL import ImageChops
#打開圖片
imga=Image.open('blend1.jpg')
imgb=Image.open('blend2.jpg')
#使用反色函數(shù) invert()
ImageChops.invert(imga).show()8.比較函數(shù) difference(),可以逐像素做減法操作,計(jì)算出絕對(duì)值。函數(shù) difference()能夠兩幅圖像的對(duì)應(yīng)像素值相減后的圖像,對(duì)應(yīng)像素值相同的,則為黑色。函數(shù) difference()通常用來(lái)找出圖像之間的差異。具體語(yǔ)法如下所示:
ImageChops.difference(image1,image2 )
其對(duì)應(yīng)像素的計(jì)算公式如下所示:
out = abs(image1 - image2)
【示例】使用 difference 圖片合成
from PIL import Image
from PIL import ImageChops
#打開圖片imga=Image.open('blend1.jpg')
imgb=Image.open('blend2.jpg')
#使用比較函數(shù) difference()
ImageChops.difference(imga,imgb).show()ImageEnhance 模塊
內(nèi)置的 ImageEnhance 模塊中包含了多個(gè)用于增強(qiáng)圖像效果的函數(shù),主要用來(lái)調(diào)整圖像的色彩、對(duì)比度、亮度和清晰度等,感覺(jué)上和調(diào)整電視機(jī)的顯示參數(shù)一樣。
在模塊 ImageEnhance 中,所有的圖片增強(qiáng)對(duì)象都實(shí)現(xiàn)一個(gè)通用的接口。這個(gè)接口只包含如下一個(gè)方法。
方法 enhance()會(huì)返回一個(gè)增強(qiáng)的 Image 對(duì)象,參數(shù) factor 是一個(gè)大于 0 的浮點(diǎn)數(shù),1 表示返回原始圖片。
當(dāng)在 Python 程序中使用模塊 ImageEnhance 增強(qiáng)圖像效果時(shí),需要首先創(chuàng)建對(duì)應(yīng)的增強(qiáng)調(diào)整器,然后調(diào)用調(diào)整器輸出函數(shù),根據(jù)指定的增強(qiáng)系數(shù)(小于 1 表示減弱,大于 1 表示增強(qiáng),等于 1 表示原圖不變)進(jìn)行調(diào)整,最后輸出調(diào)整后的圖像。在模塊 ImageEnhance 中,常用的內(nèi)置函數(shù)如下所示:
- ImageEnhance.Color(image ):功能是調(diào)整圖像色彩平衡,相當(dāng)于彩色電視機(jī)的色彩調(diào)整,實(shí)現(xiàn)了上邊提到的接口的 enhance 方法。
- ImageEnhance.Contrast(image ):功能是調(diào)整圖像對(duì)比度,相當(dāng)于彩色電視機(jī)的對(duì)比度調(diào)整。
- ImageEnhance.Brightness(image ):功能是調(diào)整圖像亮度。
- ImageEnhance.Sharpness(image ):功能是調(diào)整圖像清晰度,用于銳化/鈍化圖片。銳化操作的 factor 是 0~2 之間的一個(gè)浮點(diǎn)數(shù)。當(dāng) factor=0 時(shí),返回一個(gè)模糊的圖片對(duì)象;當(dāng) factor=2 時(shí),返回一個(gè)銳化的圖片對(duì)象;當(dāng) factor=1 時(shí),返回原始圖片對(duì)象。
【示例】使用 ImageEnhance 實(shí)現(xiàn)圖像色彩平衡
from PIL import Image
from PIL import ImageChops,ImageEnhance
#打開圖片
imga=Image.open('blend1.jpg')
w,h=imga.size
#創(chuàng)建圖像區(qū)域
img_output=Image.new('RGB',(2*w,h))
#將創(chuàng)建的部分粘貼圖片
img_output.paste(imga,(0,0))
#調(diào)整圖像色彩平衡
nhc=ImageEnhance.Color(imga)
for ratio in [0.6,1.8]:#減弱和增強(qiáng)兩個(gè)系數(shù)
b=nhc.enhance(ratio)#增強(qiáng)處理
img_output.paste(b,(w,0))#粘貼修改后的圖像
img_output.show()執(zhí)行結(jié)果:


【示例】使用 ImageEnhance 實(shí)現(xiàn)圖像亮度
from PIL import Image
from PIL import ImageChops,ImageEnhance
#打開圖片
imga=Image.open('blend1.jpg')
w,h=imga.size
#創(chuàng)建圖像區(qū)域
img_output=Image.new('RGB',(2*w,h))
#將創(chuàng)建的部分粘貼圖片
img_output.paste(imga,(0,0))
#調(diào)整圖像的亮度
nhb=ImageEnhance.Brightness(imga)
for ratio in [0.6,1.8]:#減弱和增強(qiáng)兩個(gè)系數(shù)
b=nhb.enhance(ratio)#增強(qiáng)處理
img_output.paste(b,(w,0))#粘貼修改后的圖像
img_output.show()

【示例】使用圖像點(diǎn)運(yùn)算實(shí)現(xiàn)圖像整體變暗、變亮
from PIL import Image
#打開圖片
imga=Image.open('blend1.jpg')
w,h=imga.size
#創(chuàng)建圖像區(qū)域
img_output=Image.new('RGB',(3*w,h))
#將創(chuàng)建的部分粘貼圖片
img_output.paste(imga,(0,0))
imgb=imga.point(lambda i:i*1.3)
img_output.paste(imgb,(w,0))
imgc=imga.point(lambda i:i*0.4)
img_output.paste(imgc,(2*w,0))
img_output.show()執(zhí)行結(jié)果如下圖:

ImageDraw 模塊
ImageDraw 模塊實(shí)現(xiàn)了繪圖功能。可以通過(guò)創(chuàng)建圖片的方式來(lái)繪制 2D 圖像;還可以在原有的圖片上進(jìn)行繪圖,已達(dá)到修飾圖片或?qū)D片進(jìn)行注釋的目的。
在 ImageDraw 模塊繪圖時(shí)需要首先創(chuàng)建一個(gè) ImageDraw.Draw 對(duì)象,并且提供指向文件的參數(shù)。然后引用創(chuàng)建的 Draw 對(duì)象方法進(jìn)行繪圖。最后保存或直接輸出繪制的圖像。
drawObject=ImageDraw.Draw(black)
1.繪制直線
drawObject.line([x1,y1,x2,y2],fill = None,width = 0,joint = None )
表示以(x1,y1)為起始點(diǎn),以(x2,y2)為終止點(diǎn)畫一條直線。[x1,y1,x2,y2]也可以寫為(x1,y1,x2,y2)、[(x1,y1),(x2,y2)]等;fill 用于設(shè)置指定線條顏色;width 設(shè)置線條的寬度;joint 表示一系列線之間的聯(lián)合類型。它可以是“曲線”。
2.繪制圓弧
drawObject.arc([x1,y1,x2,y2],start,end,fill = None,width = 0 )
在左上角坐標(biāo)為(x1,y1),右下角坐標(biāo)為(x2,y2)的矩形區(qū)域內(nèi),滿圓 O 內(nèi),以 start 為起始角度,以 end 為終止角度,截取圓 O 的一部分圓弧并畫出來(lái)。如果[x1,y1,x2,y2]區(qū)域不是正方形,則在該區(qū)域內(nèi)的最大橢圓中根據(jù)角度截取片段。參數(shù) fill 和 width 與 line 方法相同。
3.繪制橢圓
drawObject.ellipse([x1,y1,x2,y2],fill = None,outline = None,width = 0 )
用法同 arc 類似,用于畫圓(或者橢圓)。outline 表示只規(guī)定圓的顏色。
4.繪制弦
drawObject.chord([x1,y1,x2,y2],start,end,fill = None,outline = None,width = 0 )
用法同 arc 類似,用于畫圓中從 start 到 end 的弦。fill 表示弦與圓弧之間空間用指定顏色填滿,設(shè)置為 outline 表示只規(guī)定弦線的顏色。
5.繪制扇形
drawObject.pieslice([x1,y1,x2,y2],start,end,fill = None,outline = None,width = 0 )
用法同 elipse 類似,用于畫起止角度間的扇形區(qū)域。fill 表示將扇形區(qū)域用指定顏色填滿,設(shè)置為 outline 表示只用指定顏色描出區(qū)域輪廓。
6.繪制多邊形
drawObject.polygon([x1,y1,x2,y2,…],fill = None,outline = None )
根據(jù)坐標(biāo)畫多邊形,Python 會(huì)根據(jù)第一個(gè)參量中的(x,y)坐標(biāo)對(duì),連接出整個(gè)圖形。
fill 表示將多邊形區(qū)域用指定顏色填滿,outline 只用于設(shè)置指定顏色描出區(qū)域輪廓。
7.繪制矩形
drawObject.rectangle([x1,y1,x2,y2],fill = None,outline = None,width = 0 )
在指定的區(qū)域內(nèi)畫一個(gè)矩形,(x1,y1)表示矩形左上角的坐標(biāo),(x2,y2)表示矩形右下角的坐標(biāo)。fill 用于將矩形區(qū)域顏色填滿,outline 用于描出區(qū)域輪廓。
8.繪制文字
drawObject.text(position,text,fill = None,font = None,anchor = None,spacing = 0,align =“l(fā)eft”,direction = None,features = None,language = None )
在圖像內(nèi)添加文字。其中參數(shù) position 是一個(gè)二元組,用于指定文字左上角的坐標(biāo);text 表示要寫入的文字內(nèi)容;fill 表示文本的顏色;font 必須為 ImageFont 中指定的 font 類型; spacing 表示行之間的像素?cái)?shù);align 表示位置“left”,“center”或“right”;direction 表示文字的方向。它可以是’rtl’(從右到左),‘ltr’(從左到右)或’ttb’(從上到下)。
9.繪制點(diǎn)
drawObject.point(xy,fill = None )
給定坐標(biāo)處繪制點(diǎn)(單個(gè)像素)。
【示例】創(chuàng)建圖片的方式來(lái)繪制
from PIL import Image,ImageDraw
a=Image.new('RGB',(200,200),'white')
#新建一幅白色背景的圖像
drw=ImageDraw.Draw(a)
drw.rectangle((50,50,150,150),outline='red')
drw.text((60,60),'First Draw...',fill='green')
a.show()
【示例】在原圖片上繪制
from PIL import Image, ImageDraw
img = Image.open("lena.jpg")
draw = ImageDraw.Draw(img)
width, height = img.size
draw.arc( (0, 0, width-1, height-1), 0, 360, fill='blue')
img.save("circle.jpg")ImageFont 模塊
ImageFont 的功能是實(shí)現(xiàn)對(duì)字體和字型的處理。比較常用的內(nèi)置函數(shù)如下所示:
1.load():從指定的文件中加載一種字體,該函數(shù)返回對(duì)應(yīng)的字體對(duì)象。如果該函數(shù)運(yùn)行失敗,那么將產(chǎn)生 IOError 異常。語(yǔ)法格式如下:
ImageFont.load(文件名)
2.load_path():和函數(shù) load()一樣,但是如果沒(méi)有指定當(dāng)前路徑,就會(huì)從文件 sys.path 開始查找指定的字體文件。語(yǔ)法格式如下:
ImageFont.load_path(文件名)
3.truetype():有兩種定義格式。第 1 種格式的功能是加載一個(gè) TrueType 或者 OpenType 字體文件,并且創(chuàng)建一個(gè)字體對(duì)象。在 Windows 系統(tǒng)中,如果指定的文件不存在,加載器就會(huì)順便看看 Windows 的字體目錄下它是否存在。語(yǔ)法格式如下:
ImageFont.truetype(file,size)
第 2 種格式的功能是,加載一個(gè) TrueType 或者 OpenType 字體文件,并且創(chuàng)建一個(gè)字體對(duì)象。通常的編碼方式是“unic”(Unicode)、“symb”(MicrosoftSymbol)、“ADOB”
(Adobe Standard)、“ADBE”(Adobe Expert)和“armn”(Apple Roman)。語(yǔ)法格式如下:
ImageFont.truetype(file,size,encoding=value)
4.load_default():功能是加載一種默認(rèn)的字體。
ImageFont.load_default()
5.getsize():返回給定文本的寬度和高度,返回值是一個(gè)二元組。具體語(yǔ)法格式如下:
ImageFont.getsize()
【示例】在原圖片上繪制
from PIL import Image,ImageDraw,ImageFont
im = Image.open("bjsxt.png")
draw = ImageDraw.Draw(im)
ft=ImageFont.truetype('SIMYOU.TTF',16)
draw.text((30,30),u' 圖 像 處 理 庫(kù) PIL',font=ft,fill='red') ft=ImageFont.truetype('C:\\Windows\\Fonts\\SIMLI.TTF',20)
draw.text((30,80),u'圖像處理庫(kù) PIL',font=ft,fill='blue')
ft=ImageFont.truetype('C:\\Windows\\Fonts\\STXINGKA.TTF',30)
draw.text((30,130),u'圖像處理庫(kù) PIL',font=ft,fill='green')
im.show()
操作示例
【示例】繪制十字
from PIL import Image, ImageDraw
im = Image.open("img1.jpg")
draw = ImageDraw.Draw(im)
draw.line((0, 0) + im.size, fill=128,width=5)
draw.line((0, im.size[1], im.size[0], 0), fill=128,width=5)
im.show()執(zhí)行結(jié)果:

【示例】繪制驗(yàn)證碼
from PIL import Image, ImageFilter, ImageFont, ImageDraw import random
width=100 height=100
#最后一個(gè)參數(shù)是背景顏色,像素默認(rèn)值
im = Image.new("RGB",(width,height),(255,255,255)) draw = ImageDraw.Draw(im)
#獲取顏色
def get_color1():
return (random.randint(200, 255), random.randint(200, 255), random.randint(200, 255))
# 獲取一個(gè)字母或數(shù)字
def get_char():
return chr(random.randint(65,90))
#填充每個(gè)像素
for x in range(width):
for y in range(height):
draw.point((x,y),fill=get_color1())
font = ImageFont.truetype('simsun.ttc', 36)
for i in range(4):
draw.text((10+i*20,50),get_char(),font=font,fill=(255,0,0))
#干擾線
for i in range(2):
draw.line(((10,10),(80,80)),fill=(0,255,0),width=3)
im.show()執(zhí)行結(jié)果如下圖:

【示例】控制像素生成九宮格
from PIL import Image, ImageFilter, ImageFont, ImageDraw
width=300;height=300
x,y=0,0
im = Image.new("RGB",(width,height),(255,255,255))
#最后一個(gè)參數(shù)是背景顏色,像素默認(rèn)值
draw = ImageDraw.Draw(im)
def get_color1():
a = (x//100)+(y//100)
if a == 0:
return (255,0,0)
elif a == 1:
return (0,255,255)
elif a ==2:
return (0,0,255)
elif a==3:
return (255,255,0)
elif a==4:
return (255,0,255)
else:
return (0,0,0)
#填充每個(gè)像素
for x in range(width):
for y in range(height):
draw.point((x,y),fill=get_color1())
im.show()執(zhí)行結(jié)果如下:

【示例】將圖片中的黃色變換成紅色
from PIL import Image, ImageFilter, ImageFont, ImageDraw
im = Image.open("bjsxt.png")
draw = ImageDraw.Draw(im)
def get_color(oldColor):
'''
如果是黃色(255,255,0),則換算成紅色,把綠色通道置為 0
可以點(diǎn)擊:windows 中的畫圖軟件調(diào)色板觀察黃色的區(qū)間。
:return:
'''
print(oldColor)
if oldColor[0]>60 and oldColor[1]>60:
return (oldColor[0],0,oldColor[2])
else:
return oldColor
for x in range(im.width):
for y in range(im.height):
draw.point((x,y),fill=get_color(im.getpixel((x,y))))
im.show()執(zhí)行結(jié)果如下:


【示例】讀取圖片保存到大的一維數(shù)組
#將圖片轉(zhuǎn)換為大的一維數(shù)組保存到文件,讀取文件內(nèi)容將結(jié)果保存成圖片
from PIL import Image
import numpy as np import os
import pickle
#讀取圖片的路徑
image_dir='./images/'
#保存圖片的路徑
result_dir='./result/'
#存放數(shù)組的文件
array_file='./arr.bin'
#讀取圖片,將圖片保存到大的一維數(shù)組中
def image_to_array():
filenames=os.listdir(image_dir)
image_arr=np.array([])
for fileName in filenames:
img=Image.open(image_dir+fileName)
#將圖片按三色提取
r,g,b=img.split()
#r g b 轉(zhuǎn)換為一維數(shù)組
r_arr=np.array(r).reshape(62500)
g_arr=np.array(g).reshape(-1)
b_arr=np.array(b).reshape(-1)
#將三色拼接
arr=np.concatenate((r_arr,g_arr,b_arr))
#將 8 張圖片的 arr 拼接到一個(gè)大的一維數(shù)組中
image_arr=np.concatenate((arr,image_arr))【示例】將大的一維數(shù)組保存到文件
#一維數(shù)組保存到文件 f=open(array_file,'wb') pickle.dump(image_arr,f) f.close()
【示例】讀取文件內(nèi)容合并成圖片
#讀取文件內(nèi)容,保存圖片
def file_to_image():
with open(array_file,'rb') as f:
images=pickle.load(f)
#將一維數(shù)組轉(zhuǎn)換為 8,3,250,250
image_arr=images.reshape((8,3,250,250))
#循環(huán)遍歷每一張圖片對(duì)應(yīng)的大的數(shù)組恢復(fù)成圖片
for i in range(8):
r=Image.fromarray(image_arr[i][0]).convert('L')
g=Image.fromarray(image_arr[i][1]).convert('L')
b=Image.fromarray(image_arr[i][2]).convert('L')
image=Image.merge('RGB',(r,g,b))
#將圖片保存
image.save(result_dir+str(i)+'.jpg')到此這篇關(guān)于Python圖像處理庫(kù)Pillow的簡(jiǎn)單實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Python Pillow內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
django formset實(shí)現(xiàn)數(shù)據(jù)表的批量操作的示例代碼
這篇文章主要介紹了django-formset實(shí)現(xiàn)數(shù)據(jù)表的批量操作的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
跟老齊學(xué)Python之通過(guò)Python連接數(shù)據(jù)庫(kù)
現(xiàn)在在做python的時(shí)候需要用到數(shù)據(jù)庫(kù),于是自己重新整理了一下數(shù)據(jù)庫(kù)的知識(shí),并且熟悉了python中MysqlDB模塊的功能和函數(shù)等接口,現(xiàn)在系統(tǒng)地來(lái)總結(jié)一下吧2014-10-10
python 找出list中最大或者最小幾個(gè)數(shù)的索引方法
今天小編就為大家分享一篇python 找出list中最大或者最小幾個(gè)數(shù)的索引方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10
Python如何利用正則表達(dá)式爬取網(wǎng)頁(yè)信息及圖片
這篇文章主要給大家介紹了關(guān)于Python如何利用正則表達(dá)式爬取網(wǎng)頁(yè)信息及圖片的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
詳解Python openpyxl庫(kù)的基本應(yīng)用
這篇文章主要介紹了Python openpyxl庫(kù)的基本應(yīng)用,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2021-02-02
Python實(shí)戰(zhàn)之屏幕錄制功能的實(shí)現(xiàn)
屏幕錄制,即屏幕捕獲,是指將計(jì)算機(jī)屏幕上的活動(dòng)記錄下來(lái),生成視頻文件,本文 主要為大家介紹了如何使用Python實(shí)現(xiàn)這一功能,希望對(duì)大家有所幫助2025-03-03
python神經(jīng)網(wǎng)絡(luò)Keras常用學(xué)習(xí)率衰減匯總
這篇文章主要為大家介紹了python神經(jīng)網(wǎng)絡(luò)Keras常用學(xué)習(xí)率衰減匯總,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
利用PyQt中的QThread類實(shí)現(xiàn)多線程
本文主要給大家分享的是python實(shí)現(xiàn)多線程及線程間通信的簡(jiǎn)單方法,非常的實(shí)用,有需要的小伙伴可以參考下2020-02-02
Python中解析JSON并同時(shí)進(jìn)行自定義編碼處理實(shí)例
這篇文章主要介紹了Python中解析JSON并同時(shí)進(jìn)行自定義編碼處理實(shí)例,需要的朋友可以參考下2015-02-02

