iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 24
1
自我挑戰組

原來電腦可以這樣用!? 果蠅也懂的程式語言教學系列 第 24

Day24-Python 影像處理套件 PIL

PIL(Pillow) 是 Python 中著名的影像處理套件,以前在 Python2 的時代是 PIL,到 Python3 fork 出一個可相容新版的 Pillow,可以用來轉檔、調色、濾鏡、浮水印甚至創造圖片一堆的功能,雖然不能像 photoshop 之類的軟體一樣強大,但他可以透過程式語言批次處理大量的檔案,在其他需要用到圖片的應用也有很大的幫助。

在寫這篇的時候我特地去仔細看了 PIL 文件,才發現影像其實相當複雜,裡面保存了各種數值,每一種格式又有不同,影像不是我的專業,讀起來是在有些吃力阿~


安裝

pipenv --python 3.7
pipenv shell
pipenv install Pillow

轉檔

最簡單的轉檔方式,就是利用 PIL.Image 讀入格式A的檔案,然後以格式B儲存。

Image.open() 讀取圖片檔
save("FILE NAME","FORMAT") 用來寫入圖片檔,format 其實非必須,PIL會自動透過常見副檔名來判斷格式。

from PIL import Image

im = Image.open("test.jpg")
im.save("test.png","png")
from PIL import Image

im = Image.open("test.jpg")
im.save("test.tiff","tiff")
from PIL import Image

im = Image.open("test.jpg")
im.save("test.pdf","pdf")

常用的 PIL 支援格式

  • BMP
  • EPS
  • GIF
  • JPEG
  • PNG
  • TIFF
  • PDF

將目錄下所有 jpg 檔轉換為特定格式

Usage: python convert.py [Format]
e.g. python convert.py png

from glob import glob
from os.path import splitext
from PIL import Image
import sys

if(len(sys.argv) != 2):
    exit("參數錯誤")

userFormat = sys.argv[1]

jpglist = glob("*.[jJ][pP][gG]")

for jpg in jpglist:
    try:
        im = Image.open(jpg)
        pic = splitext(jpg)[0] + "." + userFormat
        im.save(pic)
        print(pic)
    except expression as identifier:
        print(identifier)

修改突變尺寸

我們可以透過 resize() 方法重新設定影像尺寸,第一個參數輸入(寬,高),第二個參數可輸可不輸,預設為 Image.BILINEAR,注意這個改變尺寸的方法不會自己幫我們等比例縮放,所以我們要算出正確的比例,如下列程式碼中ratio = float(width)/im.size[0] 的部分。

from PIL import Image

im = Image.open("test.jpg")
print (im.size)
width = 400
ratio = float(width)/im.size[0]
height = int(im.size[1]*ratio)
nim = im.resize( (width, height), Image.BILINEAR )
print (nim.size)
nim.save("test_resized.jpg")

原圖
https://ithelp.ithome.com.tw/upload/images/20191010/20120282kTZlaQdPOr.jpg

修改後
https://ithelp.ithome.com.tw/upload/images/20191010/20120282nvselnQcYA.jpg


JPG 壓縮

就在剛剛要上傳原圖的時候我發現檔案高達5MB,但上傳限制是2MB,就想說既然要壓縮就用 PIL 來壓縮吧! 壓縮的做法和轉檔很像,只是多設定了品質參數而已。
save()函式中加入 quality=80, subsampling=0這兩個參數即可壓縮檔案,通常 quality 會設定80或90。

from PIL import Image

img = Image.open("test.jpg")
img.save("test_c.jpg",quality=65, subsampling=0)

圖片旋轉

圖片旋轉也是很常用的功能,我來介紹一下吧,透過 transpose() 方法可以轉換圖片方向,該方法會回傳處理完的圖片,所以要用一個變數去接,transpose 內支援下面五種參數

  • Image.FLIP_LEFT_RIGHT (左右翻轉)
  • Image.FLIP_TOP_DOWN (上下翻轉)
  • Image.ROTATE_90 (旋轉90度)
  • Image.ROTATE_180 (旋轉180度)
  • Image.ROTATE_270 (旋轉270度)
from PIL import Image

img = Image.open("test.jpg")
imgR = img.transpose(Image.ROTATE_180)
imgR.save("test_R180.jpg")

旋轉後圖片
https://ithelp.ithome.com.tw/upload/images/20191010/20120282NQ5jqoSPMQ.jpg


製作縮圖

PIL有一個專門製作縮圖的方法thumbnail(),它會自動進行等比例縮放,並且選擇你傳入的長寬裡比較小的那個數據,執行速度也比 resize()

from PIL import Image

img = Image.open( "test.jpg" )
img.thumbnail( (400,100) ) #指定長與寬並進行縮圖製作
img.save( "test_thumbnail.jpg" )
print (img.size)

縮圖
https://ithelp.ithome.com.tw/upload/images/20191010/20120282D4VCorxpSp.jpg


加入濾鏡

PIL 本身就有提供一些濾鏡可以使用,當然也可以下載人開發出來的濾鏡,我示範一個輪廓邊界濾鏡,雖然這張圖片有點不適合這個濾鏡,但大概就是這個意思啦~

透過 img.fliter() 即可加入濾鏡,參數則是傳入想要加上的濾鏡,例如這邊是img.filter(ImageFilter.FIND_EDGES),他會回傳處理好的影像,所以也需要一個變數來接。

from PIL import Image
from PIL import ImageFilter

img = Image.open("test_resized.jpg")
img_f = img.filter(ImageFilter.FIND_EDGES)
img_f.save("test_rf.jpg")

輪廓濾鏡處理後
https://ithelp.ithome.com.tw/upload/images/20191010/20120282ZdUvY4FUzb.jpg

到這邊就是 PIL 函式庫簡單的介紹,大家可以試著用 PI L寫一個綜合影像編輯軟體喔~


參考資料
https://pypi.org/project/Pillow/
https://yungyuc.github.io/oldtech/python/python_imaging.html
https://pillow-zh-cn.readthedocs.io/zh_CN/latest/handbook/image-file-formats.html


上一篇
Day23-Python Line 整合應用2 -- Line 對話機器人III
下一篇
Day25-Python程式包裝成 EXE 執行檔
系列文
原來電腦可以這樣用!? 果蠅也懂的程式語言教學30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
greenhat_p
iT邦新手 5 級 ‧ 2020-04-25 10:56:08

那要怎麼設定最後存檔在哪

我要留言

立即登入留言