PIL官方文檔:ide
http://effbot.org/imagingbook/函數
1、PIL(Python Imaging Library)的基本概念spa
PIL中所涉及的基本概念有以下幾個:通道(bands)、模式(mode)、尺寸(size)、座標系統(coordinate system)、調色板(palette)、信息(info)和濾波器(filters)。code
一、通道orm
每張圖片都是由一個。或者多個數據通道構成。PIL容許在單張圖片中合成相同維數和深度的多個通道。視頻
以RGB圖像爲例,每張圖片都是由三個數據通道構成,分別爲R、G和B通道。而對於灰度圖像,則只有一個通道。對象
二、模式blog
圖像的模式定義了圖像的類型和像素的位寬。當前支持以下模式:圖片
1:1位像素,表示黑和白,可是存儲的時候每一個像素存儲爲8bit。文檔
L:8位像素,表示黑和白。
P:8位像素,使用調色板映射到其餘模式。
RGB:3x8位像素,爲真彩色。
RGBA:4x8位像素,有透明通道的真彩色。
CMYK:4x8位像素,顏色分離。
YCbCr:3x8位像素,彩色視頻格式。
I:32位整型像素。
F:32位浮點型像素。
PIL也支持一些特殊的模式,包括RGBX(有padding的真彩色)和RGBa(有自左乘alpha的真彩色)。
三、尺寸
經過size屬性能夠獲取圖片的尺寸。這是一個二元組,包含水平和垂直方向上的像素數。
四、座標系統
PIL使用笛卡爾像素座標系統,座標(0,0)位於左上角。注意:座標值表示像素的角;位於座標(0,0)處的像素的中心實際上位於(0.5,0.5)。
座標常常用於二元組(x,y)。長方形則表示爲四元組,前面是左上角座標。例如,一個覆蓋800x600的像素圖像的長方形表示爲(0,0,800,600)。
五、調色板
調色板模式 ("P")使用一個顏色調色板爲每一個像素定義具體的顏色值
六、信息
使用info屬性能夠爲一張圖片添加一些輔助信息。這個是字典對象。加載和保存圖像文件時,多少信息須要處理取決於文件格式。
七、濾波器
對於將多個輸入像素映射爲一個輸出像素的幾何操做,PIL提供了4個不一樣的採樣濾波器:
NEAREST:最近濾波。從輸入圖像中選取最近的像素做爲輸出像素。它忽略了全部其餘的像素。
BILINEAR:雙線性濾波。在輸入圖像的2x2矩陣上進行線性插值。注意:PIL的當前版本,作下采樣時該濾波器使用了固定輸入模板。
BICUBIC:雙立方濾波。在輸入圖像的4x4矩陣上進行立方插值。注意:PIL的當前版本,作下采樣時該濾波器使用了固定輸入模板。
ANTIALIAS:平滑濾波。這是PIL 1.1.3版本中新的濾波器。對全部能夠影響輸出像素的輸入像素進行高質量的重採樣濾波,以計算輸出像素值。在當前的PIL版本中,這個濾波器只用於改變尺寸和縮略圖方法。
注意:在當前的PIL版本中,ANTIALIAS濾波器是下采樣(例如,將一個大的圖像轉換爲小圖)時惟一正確的濾波器。BILIEAR和BICUBIC濾波器使用固定的輸入模板,用於固定比例的幾何變換和上採樣是最好的。
2、PIL模塊中經常使用的類
PIL模塊中經常使用的最重要的類是Image類,須要在程序中引入Image。Image經常使用的方法有:
Open():打開一張圖片,方法內需傳入圖片的名稱,即:路徑+文件名.後綴名,例如:Image.open(「pic14.jpg」),open()方法會返回一個Image對象,咱們能夠使用Image的方法來獲取該對象的屬性。
對象名.format():獲取圖像的格式,如:jpg,jpeg,ppm等。
對象名.size:獲取圖像的大小尺寸
對象名.mode:獲取圖像的顏色屬性,灰度圖或RGB
對象名.show():將圖片顯示出來
對象名.save(arg1,arg2):將圖片保存,arg1是圖片保存的名稱,即:路徑+文件名,arg2是圖片保存的格式。
對象名.crop(arg):截取圖片的某一部分,參數arg是一個元組類型的變量,形式爲:(left,upper,right,lower)。在PIL的座標系中,圖片的左上角是座標系的原點。這裏的(left,upper,right,lower)表明的是截取部分的座標,用(left,upper)座標表示截取區域的左上角點,用(right,lower)座標表明截取區域的右下角點,這樣的話,區域的位置和大小就都肯定了。
對象名.split():將圖片的幾個通道分開,例如:r,g,b=im.split()
Image.merge(「RGB」,(b,g,r)):將圖片的通道分開後從新組合獲得一張新的圖片。
3、案例代碼
一、打開一張圖片,而後顯示並獲取圖片的尺寸大小,並生成縮略圖
代碼:
import os, sys from PIL import Image,ImageFilter,ImageDraw im=Image.open("pic01.jpg") im.show() xsize,ysize=im.size im.thumbnail((xsize//2,ysize//2)) im.save("thumb_pic01.jpg","JPEG")
程序結果:
(1024, 638)
程序會使用系統默認的圖片查看器將圖片顯示出來,並以二元組的形式將圖片的尺寸打印出來。在生成縮略圖時,須要將縮略圖的尺寸以元組的形式傳入,而後保存。
二、將圖片旋轉90°並保存
代碼:
import os, sys from PIL import Image,ImageFilter,ImageDraw im = Image.open("pic01.jpg") im=im.resize((im.size[0]//2,im.size[1]//2)) out=im.rotate(90).save("pic01_rotate_90.jpg")
程序結果:
程序運行結果:將rotate方法返回的圖片以指定的名稱存儲起來,打開圖片發現圖片被裁剪了。也能夠使用transpose()方法對圖片進行上下翻轉、左右翻轉,旋轉等操做。示例以下:
import os, sys from PIL import Image,ImageFilter,ImageDraw im = Image.open("pic01.jpg") out=im.transpose(Image.FLIP_LEFT_RIGHT)#將圖片進行左右翻轉操做 out.show() out=im.transpose(Image.FLIP_TOP_BOTTOM)#將圖片進行上下翻轉操做 out.show() out=im.transpose(Image.ROTATE_180)#將圖片旋轉180° out.show()
三、 截取圖片並實現將圖片沿着某一方向滑動的效果
首先咱們須要定義一個函數以實現讓圖片沿着x方向滑動,代碼以下:
import os, sys from PIL import Image,ImageFilter,ImageDraw def roll_x_side(image, delta): "Roll an image sideways" xsize, ysize = image.size delta = delta % xsize if delta == 0: return image part1 = image.crop((0, 0, delta, ysize)) part2 = image.crop((delta, 0, xsize, ysize)) image.paste(part2, (0, 0, xsize-delta, ysize)) image.paste(part1, (xsize-delta, 0, xsize, ysize) return image
在這裏咱們指定了滑動的距離。而後使用了crop方法,將要截取區域的左上角頂點的座標和右下角頂點的座標以一個四元組的形式傳入該方法,crop()方法會返回該區域的圖片。在獲取須要截取的區域後,再將該區域粘貼到滑動後的區域。這樣就實現了沿着x軸的滑動。實現沿着y軸滑動的函數與之相似,代碼以下:
def roll_y_side(image, delta): "Roll an image sideways" xsize, ysize = image.size delta = delta % ysize if delta == 0: return image part1 = image.crop((0, 0, xsize, delta)) part2 = image.crop((0, delta, xsize, ysize)) image.paste(part2, (0, 0, xsize, ysize-delta)) image.paste(part1, (0, ysize-delta, xsize, ysize)) return image
完整的代碼以下:
import os, sys from PIL import Image,ImageFilter,ImageDraw def roll_x_side(image, delta): "Roll an image sideways" xsize, ysize = image.size delta = delta % xsize if delta == 0: return image part1 = image.crop((0, 0, delta, ysize)) part2 = image.crop((delta, 0, xsize, ysize)) image.paste(part2, (0, 0, xsize-delta, ysize)) image.paste(part1, (xsize-delta, 0, xsize, ysize) return image def roll_y_side(image, delta): "Roll an image sideways" xsize, ysize = image.size delta = delta % ysize if delta == 0: return image part1 = image.crop((0, 0, xsize, delta)) part2 = image.crop((0, delta, xsize, ysize)) image.paste(part2, (0, 0, xsize, ysize-delta)) image.paste(part1, (0, ysize-delta, xsize, ysize)) return image im = Image.open("pic01.jpg") im_01=roll_x_side(im,300) im_01.save("pic01_x_roll.jpg") im_01.show() im_02=roll_y_side(im,300) im_02.save("pic01_y_roll.jpg") im_02.show()
四、 將彩色圖片分開成單個通道再合併
代碼:
im=Image.open("pic01.jpg")
im.show()
r, g, b = im.split()
r.show()
g.show()
b.show()#將這幾個單通道的圖片從新組合成一張新的圖片
im = Image.merge("RGB", (b, r, g))
im.show()
五、 顏色變換:將彩色圖片轉換爲灰度圖
代碼:
im = Image.open("pic01.jpg") im.show() out=im.convert("L")#將RGB格式的圖片轉換爲灰度圖 out.show() print(out.mode,out.format,out.size)
六、 圖像濾波
代碼:
im = Image.open("pic01.jpg") out=im.filter(ImageFilter.DETAIL)#細節加強 out.show() out=im.filter(ImageFilter.BLUR)#模糊化 out.show() out=im.filter(ImageFilter.CONTOUR)#輪廓濾波,將圖片的輪廓提取出來 out.show() out=im.filter(ImageFilter.EDGE_ENHANCE)#邊緣強化 out.show() out=im.filter(ImageFilter.EDGE_ENHANCE_MORE)#深度邊緣加強濾波,會使得圖像中邊緣部分更加明顯 out.show() out=im.filter(ImageFilter.EMBOSS)#浮雕濾波,會使圖像呈現出浮雕效果 out.show() out=im.filter(ImageFilter.SMOOTH)#平滑濾波 out.show()