python写gui导入图片并处理_Python图像处理库:Pillow 初级教程
Image類
Pillow中最重要的類就是Image,該類存在于同名的模塊中。可以通過以下幾種方式實例化:從文件中讀取圖片,處理其他圖片得到,或者直接創建一個圖片。
使用Image模塊中的open函數打開一張圖片:>>>?from?PIL?import?Image
>>>?im?=?Image.open("lena.ppm")
如果打開成功,返回一個Image對象,可以通過對象屬性檢查文件內容
>>>?from?__future__?import?print_function
>>>?print(im.format,?im.size,?im.mode)
PPM?(512,?512)?RGB
format屬性定義了圖像的格式,如果圖像不是從文件打開的,那么該屬性值為None;size屬性是一個tuple,表示圖像的寬和高(單位為像素);mode屬性為表示圖像的模式,常用的模式為:L為灰度圖,RGB為真彩色,CMYK為pre-press圖像。
如果文件不能打開,則拋出IOError異常。
當有一個Image對象時,可以用Image類的各個方法進行處理和操作圖像,例如顯示圖片:>>>?im.show()
ps:標準版本的show()方法不是很有效率,因為它先將圖像保存為一個臨時文件,然后使用xv進行顯示。如果沒有安裝xv,該函數甚至不能工作。但是該方法非常便于debug和test。(windows中應該調用默認圖片查看器打開)
讀寫圖片
Pillow庫支持相當多的圖片格式。直接使用Image模塊中的open()函數讀取圖片,而不必先處理圖片的格式,Pillow庫自動根據文件決定格式。
Image模塊中的save()函數可以保存圖片,除非你指定文件格式,那么文件名中的擴展名用來指定文件格式。
圖片轉成jpg格式from?__future__?import?print_function
import?os,?sys
from?PIL?import?Image
for?infile?in?sys.argv[1:]:
f,?e?=?os.path.splitext(infile)
outfile?=?f?+?".jpg"
if?infile?!=?outfile:
try:
Image.open(infile).save(outfile)
except?IOError:
print("cannot?convert",?infile)
save函數的第二個參數可以用來指定圖片格式,如果文件名中沒有給出一個標準的圖像格式,那么第二個參數是必須的。
創建縮略圖from?__future__?import?print_function
import?os,?sys
from?PIL?import?Image
size?=?(128,?128)
for?infile?in?sys.argv[1:]:
outfile?=?os.path.splitext(infile)[0]?+?".thumbnail"
if?infile?!=?outfile:
try:
im?=?Image.open(infile)
im.thumbnail(size)
im.save(outfile,?"JPEG")
except?IOError:
print("cannot?create?thumbnail?for",?infile)
必須指出的是除非必須,Pillow不會解碼或raster數據。當你打開一個文件,Pillow通過文件頭確定文件格式,大小,mode等數據,余下數據直到需要時才處理。
這意味著打開文件非常快,與文件大小和壓縮格式無關。下面的程序用來快速確定圖片屬性:
確定圖片屬性from?__future__?import?print_function
import?sys
from?PIL?import?Image
for?infile?in?sys.argv[1:]:
try:
with?Image.open(infile)?as?im:
print(infile,?im.format,?"%dx%d"?%?im.size,?im.mode)
except?IOError:
pass
裁剪、粘貼、與合并圖片
Image類包含還多操作圖片區域的方法。如crop()方法可以從圖片中提取一個子矩形
從圖片中復制子圖像box?=?im.copy()?#直接復制圖像
box?=?(100,?100,?400,?400)
region?=?im.crop(box)
區域由4-tuple決定,該tuple中信息為(left, upper, right, lower)。 Pillow左邊系統的原點(0,0)為圖片的左上角。坐標中的數字單位為像素點,所以上例中截取的圖片大小為300*300像素^2。
處理子圖,粘貼回原圖region?=?region.transpose(Image.ROTATE_180)
im.paste(region,?box)
將子圖paste回原圖時,子圖的region必須和給定box的region吻合。該region不能超過原圖。而原圖和region的mode不需要匹配,Pillow會自動處理。
另一個例子Rolling?an?image
def?roll(image,?delta):
"Roll?an?image?sideways"
image?=?image.copy()?#復制圖像
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
分離和合并通道r,?g,?b?=?im.split()
im?=?Image.merge("RGB",?(b,?g,?r))
對于單通道圖片,split()返回圖像本身。為了處理單通道圖片,必須先將圖片轉成RGB。
幾何變換
Image類有resize()、rotate()和transpose()、transform()方法進行幾何變換。
簡單幾何變換out?=?im.resize((128,?128))
out?=?im.rotate(45)?#?順時針角度表示
置換圖像out?=?im.transpose(Image.FLIP_LEFT_RIGHT)
out?=?im.transpose(Image.FLIP_TOP_BOTTOM)
out?=?im.transpose(Image.ROTATE_90)
out?=?im.transpose(Image.ROTATE_180)
out?=?im.transpose(Image.ROTATE_270)
transpose()和象的rotate()沒有性能差別。
更通用的圖像變換方法可以使用transform()
模式轉換
convert()方法
模式轉換im?=?Image.open('lena.ppm').convert('L')
圖像增強
Filter
ImageFilter模塊包含很多預定義的增強filters,通過filter()方法使用
應用filtersfrom?PIL?import?ImageFilter
out?=?im.filter(ImageFilter.DETAIL)
像素點處理
point()方法通過一個函數或者查詢表對圖像中的像素點進行處理(例如對比度操作)。
像素點變換#?multiply?each?pixel?by?1.2
out?=?im.point(lambda?i:?i?*?1.2)
上述方法可以利用簡單的表達式進行圖像處理,通過組合point()和paste()還能選擇性地處理圖片的某一區域。
處理單獨通道#?split?the?image?into?individual?bands
source?=?im.split()
R,?G,?B?=?0,?1,?2
#?select?regions?where?red?is?less?than?100
mask?=?source[R].point(lambda?i:?i?
#?process?the?green?band
out?=?source[G].point(lambda?i:?i?*?0.7)
#?paste?the?processed?band?back,?but?only?where?red?was?
source[G].paste(out,?None,?mask)
#?build?a?new?multiband?image
im?=?Image.merge(im.mode,?source)
注意到創建mask的語句:mask?=?source[R].point(lambda?i:?i?
該句可以用下句表示imout?=?im.point(lambda?i:?expression?and?255)
如果expression為假則返回expression的值為0(因為and語句已經可以得出結果了),否則返回255。(mask參數用法:當為0時,保留當前值,255為使用paste進來的值,中間則用于transparency效果)
高級圖片增強
對其他高級圖片增強,應該使用ImageEnhance模塊 。一旦有一個Image對象,應用ImageEnhance對象就能快速地進行設置。 可以使用以下方法調整對比度、亮度、色平衡和銳利度。
圖像增強from?PIL?import?ImageEnhance
enh?=?ImageEnhance.Contrast(im)
enh.enhance(1.3).show("30%?more?contrast")
動態圖
Pillow支持一些動態圖片的格式如FLI/FLC,GIF和其他一些處于實驗階段的格式。TIFF文件同樣可以包含數幀圖像。
當讀取動態圖時,PIL自動讀取動態圖的第一幀,可以使用seek和tell方法讀取不同幀。from?PIL?import?Image
im?=?Image.open("animation.gif")
im.seek(1)?#?skip?to?the?second?frame
try:
while?1:
im.seek(im.tell()+1)
#?do?something?to?im
except?EOFError:
pass?#?end?of?sequence
當讀取到最后一幀時,Pillow拋出EOFError異常。
當前版本只允許seek到下一幀。為了倒回之前,必須重新打開文件。
或者可以使用下述迭代器類
動態圖迭代器類class?ImageSequence:
def?__init__(self,?im):
self.im?=?im
def?__getitem__(self,?ix):
try:
if?ix:
self.im.seek(ix)
return?self.im
except?EOFError:
raise?IndexError?#?end?of?sequence
for?frame?in?ImageSequence(im):
#?...do?something?to?frame...
Postscript?Printing
Pillow允許通過Postscript Printer在圖片上添加images、text、graphics。Drawing?Postscript
from?PIL?import?Image
from?PIL?import?PSDraw
im?=?Image.open("lena.ppm")
title?=?"lena"
box?=?(1*72,?2*72,?7*72,?10*72)?#?in?points
ps?=?PSDraw.PSDraw()?#?default?is?sys.stdout
ps.begin_document(title)
#?draw?the?image?(75?dpi)
ps.image(box,?im,?75)
ps.rectangle(box)
#?draw?centered?title
ps.setfont("HelveticaNarrow-Bold",?36)
w,?h,?b?=?ps.textsize(title)
ps.text((4*72-w/2,?1*72-h),?title)
ps.end_document()
ps:textsize不能用,有誰知道嗎
更多讀取圖片方法
之前說到Image模塊的open()函數已經足夠日常使用。該函數的參數也可以是一個文件對象。
從string中讀取import?StringIO
im?=?Image.open(StringIO.StringIO(buffer))
從tar文件中讀取from?PIL?import?TarIO
fp?=?TarIO.TarIO("Imaging.tar",?"Imaging/test/lena.ppm")
im?=?Image.open(fp)
草稿模式
draft()方法允許在不讀取文件內容的情況下盡可能(可能不會完全等于給定的參數)地將圖片轉成給定模式和大小,這在生成縮略圖的時候非常有效(速度要求比質量高的場合)。
draft模式from?__future__?import?print_function
im?=?Image.open(file)
print("original?=",?im.mode,?im.size)
im.draft("L",?(100,?100))
print("draft?=",?im.mode,?im.size)
總結
以上是生活随笔為你收集整理的python写gui导入图片并处理_Python图像处理库:Pillow 初级教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java竞选组长发言_竞选组长的发言稿_
- 下一篇: java中的JDBC用户管理系统_Jav