原文:
https://pillow-cn.readthedocs.io/zh_CN/latest/reference/Image.html
中文版參考文檔不全,所以自己試着翻譯了一下,以下~備注部分,測試程序為自己添加~
PIL安裝
下載地址:https://pypi.org/simple/pillow/
找到對應自己Python版本的安裝包,比方我的Python版本是3.7,64位的,就下載了Pillow-6.1.0-cp37-cp37m-win_amd64.whl
Image模塊
Image模塊提供一個同名的類用來表示一張PIL圖像,該模塊也提供很多工廠函數,用來從文件中載入圖片或者創建新圖片。
例子
以下腳本載入一張圖片,旋轉45度,將其顯示在外部預覽窗口上(通常Unix系統使用XV...?...,Windows系統使用畫圖程序)
打開,旋轉,用默認圖片瀏覽器顯示一張圖片
from PIL import Image
im = Image.open("bride.jpg")im.rotate(45).show()
備注(im.rotate()傳入正值逆時針旋轉,傳入負值順時針旋轉)
以下腳本為當前目錄所有jpeg圖片創建完美的128x128尺寸縮略圖
創建縮略圖
from PIL import Image import glob,os size=(128,128) for infile in glob.glob("*.jpg"): (file,ext)=os.path.splitext(infile) im=Image.open(infile) im.thumbnail(size,Image.ANTIALIAS) im.save(file+".thumbnail.jpeg","JPEG")
備注
- glob為python自帶庫,glob.glob("*.jpg")返回當前文件夾下所有jpg文件名,不包含路徑
- os.path.spiltext(file),將比如xxx.jpg字符串分割為xxx和.jpg並返回分割結果
- 運行該程序應該事先在當下目錄放一些jpg格式圖片文件
函數
PIL.Image.open(fp, mode='r')
打開給定的圖片文件,並返回文件標識
這是一個延時操作,該函數取得文件標識之后,文件保持被打開狀態。並且在你處理數據之前,該函數不會去讀取文件中的數據。
參數:
·file——一個文件名字符串或者一個文件對象。如果是文件對象,必須執行read(),seek()或tell()方法,並且用二進制模式打開
·mode——打開模式,如果給定,參數必須是”r”
返回:一個Image objet
引發IOError:如果文件不存在,或者文件無法識別
備注:當使用Image.open("C:\Users\Administrator\Desktop\1.jpg")打開一張圖片時,可能會報錯
nunicodeessscape codec can't decode bytes in xxx:truncated\UXXXXXXXX escape,改成Image.open(r"C:\Users\Administrator\Desktop\1.jpg")就好了
圖片處理
PIL.Image.alpha_composite(im1, im2)
圖像通道融合,把m2復合在m1上(原文Alpha composite im2 over im1)
參數:
·im1,第一張圖片
·im2,第二章圖片,必須和第一張圖片具有相同的模式(備注,貌似只能都是RGBA格式),尺寸
返回:一個圖片對象
測試程序:
from PIL import Image img1=Image.open(r"C:\Users\Administrator\Desktop\1.jpg").convert(mode="RGBA") img2=Image.open(r"C:\Users\Administrator\Desktop\1.jpg").convert(mode="RGBA") newImg=Image.alpha_composite(img1,img2) newImg.show()
這個貌似沒什么效果,這個函數只能融合兩個大小一樣的RGBA格式圖片,所以這里用了convert(mode="RGBA")
轉化成RGBA格式,否則就會報錯
PIL.Image.blend(im1, im2, alpha)
使用一個alpha常量,融合兩張輸入的圖片,產生一張新圖片
計算方法:
out = image1 * (1.0 - alpha) + image2 * alpha
參數
·im1——第一張圖片
·im2——第二張圖片,與第一張圖片具有相同的模式和尺寸
·alpha——插入的alpha因子,如果值為0.0,返回第一張圖片的拷貝,如果值為1.0,返回第二章圖片的拷貝,對於alpha的值沒有限制...
返回:一個圖片對象
測試程序:
from PIL import Image img1=Image.open(r"C:\Users\Administrator\Desktop\1.jpg").convert(mode="RGBA") img2=Image.new("RGBA",img1.size,"red") newImg=Image.blend(img1,img2,0.5) newImg.show()
這個程序是蠻有意思的,會在第一張圖片上加上一層紅色遮罩
參考:https://www.cnblogs.com/Lival/p/6211602.html
PIL.Image.composite(image1, image2, mask)
通過在融合圖像的基礎上,加入一個具有透明度的遮罩來創建一張復合圖(原文:Create composite image by blending images using a transparency mask)
參數
·image1——第一張圖片
·image2——第二張圖片,與第一張圖片具有相同模式和尺寸
·mask——一張mask圖片,這張圖片可以是 “1”, “L”, or “RGBA”模式的,且必須與前兩張圖片具有相同的尺寸
測試程序
from PIL import Image img1=Image.open(r"C:\Users\Administrator\Desktop\1.jpg") img2=Image.open(r"C:\Users\Administrator\Desktop\2.jpg") (r,g,b)=img2.split() newImg=Image.composite(img1,img2,b) newImg.show()
這個程序選擇圖片比較重要,不然就沒有效果,第一章圖片為背景為白色效果比較明顯點
參考:https://blog.csdn.net/MiniCatTwo/article/details/80566129
PIL.Image.eval(image, *args)
使用函數操作圖片的每一個像素位(該函數應該帶有一個參數)
參數,如果圖片有多個波段,那么函數將應用於圖片的每個波段。該函數對每個像素位只計算一次,所以不能使用隨機數或者其他生成器。
·image——輸入圖片
·function——一個函數對象,帶一個整型參數
測試程序
from PIL import Image img1=Image.open(r"C:\Users\Administrator\Desktop\1.jpg") newImg=Image.eval(img1,lambda x:x*6) newImg.show()
截止現在,我對於像素位操作所產生的結果不清楚,所以函數就只好隨便寫
PIL.Image.merge(mode, bands)
將一組單波段圖片合並到一個多波段圖片中
參數
·mode——輸出圖片的模式
·bands——單波段圖片的序列,序列中所有波段必須有相同尺寸
測試程序
from PIL import Image img1=Image.open(r"C:\Users\Administrator\Desktop\1.jpg") img2=Image.open(r"C:\Users\Administrator\Desktop\2.jpg") (r1,g1,b1)=img1.split() (r2,g2,b2)=img2.split() temp=[r1,g2,b1] newImg=Image.merge("RGB",temp) newImg.show()
參考:https://blog.csdn.net/minicattwo/article/details/80572152
構造圖片
PIL.Image.new(mode, size, color=0)
創新一張新圖,用給定的模式和尺寸
參數
·mode——新圖使用的模式
·size——一個包含兩個值的元組,設置圖片寬高
·color——設置圖片顏色,默認是黑色。當給定值,如果是單個整型或者浮點型數值,表示創建單一波段圖片;如果是一個元組則表示創建多波段的圖片(元組的一個值創建一個波段)。當創建RGB圖片的時候,你還可以使用ImageColor模塊支持的顏色。如果顏色值為空,則圖片不將初始化。
返回:一個圖片對象
測試代碼
from PIL import Image #new1=Image.new("L",(400,400),"red") #new1=Image.new("P",(400,400),20) new1=Image.new("P",(400,400),(63,136,191)) new1.show()
關於圖片模式
The mode of an image defines the type and depth of a pixel in the image. The current release supports the following standard modes:
1 (1-bit pixels, black and white, stored with one pixel per byte)
L (8-bit pixels, black and white)
P (8-bit pixels, mapped to any other mode using a color palette)
RGB (3x8-bit pixels, true color)
RGBA (4x8-bit pixels, true color with transparency mask)
CMYK (4x8-bit pixels, color separation)
YCbCr (3x8-bit pixels, color video format)
Note that this refers to the JPEG, and not the ITU-R BT.2020, standard
LAB (3x8-bit pixels, the L*a*b color space)
HSV (3x8-bit pixels, Hue, Saturation, Value color space)
I (32-bit signed integer pixels)
F (32-bit floating point pixels)
如1表示,1比特像素(大概一個像素一位就可以表示出來?因為要么黑要么白色),黑白兩色,每個字節存儲一個像素...
測試一下,把彩色圖片編程黑白色:
from PIL import Image img1=Image.open(r"C:\Users\Administrator\Desktop\mylove.jpg").convert(mode="L") img1.show()
關於圖片模式轉換可以參考:
https://blog.csdn.net/icamera0/article/details/50843172
https://blog.csdn.net/icamera0/article/details/50843196
這個我也不知道有什么用...
PIL.Image.fromarray(obj, mode=None)
利用數組數據創建一塊圖片內存
If obj is not contiguous, then the tobytes method is called and frombuffer() is used
參數
·obj——數組對象
·mode——使用的模式
返回:一個圖片內存
測試程序:
import numpy as np from PIL import Image array = np.ones((40,40))*150 img=Image.fromarray(array).convert("RGB").show() print(array) print(img.getpixel((30,30)))
這個程序借鑒stackoverflow上網友的回答,顯示一塊長寬30的圖片。用到了numpy,這個模塊的功能不要太強大,可以生成數組,矩陣什么的,看到某些函數也讓我一頭霧水,看來得好好研究了。在這里 np.ones((40,40))*150表示生成一個40行,40列,元素為1的numpy數組,后面乘以150表示將數組元素的值都乘以150
之前看到一個程序,是用numpy庫的meshgrid生成一個圓的矩陣,這可能涉及到圖論里的圖的矩陣表示了,我一臉懵比,以后等學numpy庫的時候再說吧還是
先寫個簡單的:
import numpy as np from PIL import Image array=[ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, 0,0,0,0,0,0,1,0,1,0,0,0,0,0,0, 0,0,0,0,0,1,0,0,0,1,0,0,0,0,0, 0,0,0,0,1,0,0,0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0,0,0,0,1,0,0,0, 0,0,1,0,0,0,0,0,0,0,0,0,1,0,0, 0,1,0,0,0,0,0,0,0,0,0,0,0,1,0, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 0,1,0,0,0,0,0,0,0,0,0,0,0,1,0, 0,0,1,0,0,0,0,0,0,0,0,0,1,0,0, 0,0,0,1,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0,0,0,1,0,0,0,0, 0,0,0,0,0,1,0,0,0,1,0,0,0,0,0, 0,0,0,0,0,0,1,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,] nr=np.reshape(array,(15,15))*255 img=Image.fromarray(nr).convert("RGB") print(nr) print(img.getpixel((0,7))) img.show() img.save("paint.jpg")
這個程序輸出nr矩陣是這樣
[[ 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 255 0 255 0 0 0 0 0 0]
[ 0 0 0 0 0 255 0 0 0 255 0 0 0 0 0]
[ 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0]
[ 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0]
[ 0 0 255 0 0 0 0 0 0 0 0 0 255 0 0]
[ 0 255 0 0 0 0 0 0 0 0 0 0 0 255 0]
[255 0 0 0 0 0 0 0 0 0 0 0 0 0 255]
[ 0 255 0 0 0 0 0 0 0 0 0 0 0 255 0]
[ 0 0 255 0 0 0 0 0 0 0 0 0 255 0 0]
[ 0 0 0 255 0 0 0 0 0 0 0 255 0 0 0]
[ 0 0 0 0 255 0 0 0 0 0 255 0 0 0 0]
[ 0 0 0 0 0 255 0 0 0 255 0 0 0 0 0]
[ 0 0 0 0 0 0 255 0 255 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0]]
圖片是一張長寬15像素,背景黑色,中間有一個旋轉90°的方框。在這里也試了一下getpixel,得到一個像素位的顏色值。