圖片加上文字浮水印
這篇文章會介紹使用 Python 的 Pillow 第三方函式庫,實作圖片加上文字的效果 ( 使用文字作為浮水印 ),最後還會搭配 glob 函式庫,實現批次加浮水印的功能。
- 本篇使用的 Python 版本為 3.7.12,所有範例可使用 Google Colab 實作,不用安裝任何軟體 ( 參考:使用 Google Colab )
- 使用 Colab 操作需要連動 Google 雲端硬碟,請參考:連動 Google Drive
安裝 Pillow
輸入下列指令安裝 Pillow,根據個人環境使用 pip 或 pip3,如果使用 Colab 或 Anaconda Jupyter,已經內建 Pillow 函式庫。
!pip install Pillow
取得文字字型檔案
要在圖片裡加入文字,首先要知道「字型檔」,字型檔可以從電腦本機取得已經安裝的字型,或前往 Google Font 下載免費的字型檔,下載字型檔後,放到指定的資料夾內,範例將字型與 Python 程式放在同一個目錄下。
替圖片加上文字
一開始先載入 Pillow 函式庫的 Image、ImageFont 和 ImageDraw 模組,Image 負責處理圖片的影像效果,ImageFont 負責讀入字型,ImageDraw 負責在圖片上繪製圖案。
from PIL import Image, ImageFont, ImageDraw
接著使用 Image.open 開啟要加文字的圖片,使用 ImageFont.truetype 讀取字型檔案 ( 第一個參數為字型檔案路徑,第二個參數為字體大小 ),接著使用 ImageDraw.Draw 的 text 方法將文字畫入圖片中 ( 第一個參數為坐標、第二個參數為文字、第三個參數為 RGB 顏色、第四個參數為字型 )。
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks') # Colab 換路徑使用
from PIL import Image, ImageFont, ImageDraw
img = Image.open('./photo.jpg') # 開啟圖片
font = ImageFont.truetype('Teko-Regular.ttf', 100) # 設定字型
draw = ImageDraw.Draw(img) # 準備在圖片上繪圖
draw.text((0,0), 'OXXO.STUDIO', fill=(255,255,255), font=font) # 將文字畫入圖片
img.save('./ok.jpg') # 儲存圖片
# img.show() # Colab 不支援直接顯示,如果使用本機環境會開啟圖片檢視器
透過取得圖片的長寬尺寸,就能夠定義文字擺放的位置 ( 由於無法知道一段文字的總寬度,如果要靠右對齊,就要先嘗試幾張圖,才能取得正確的位置 )。
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks') # Colab 換路徑使用
from PIL import Image, ImageFont, ImageDraw
img = Image.open('./photo.jpg')
w, h = img.size # 取得圖片尺寸
font = ImageFont.truetype('Teko-Regular.ttf', 100)
draw = ImageDraw.Draw(img)
draw.text((0,h-100), 'OXXO.STUDIO', fill=(255,255,255), font=font) # 使用 h-100 定位到下方
img.save('./ok.jpg')
旋轉文字浮水印
因為無法直接旋轉文字,如果要旋轉文字浮水印,必須採用類似「logo 浮水印」的做法,先使用 Image.new 產生一張空白的圖片 ( mode 設定為 RGBA,color 設定四個參數為 0,表示透明背景 ),接著將文字繪製在這張空白圖片上,旋轉有文字的圖片,再將圖片貼到原本的圖片上,就會出現旋轉文字的浮水印。
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks') # Colab 換路徑使用
from PIL import Image, ImageFont, ImageDraw
img = Image.open('./photo.jpg')
font = ImageFont.truetype('Teko-Regular.ttf', 150)
# 設定一張空白圖片,背景 (0,0,0,0) 表示透明背景
text = Image.new(mode='RGBA', size=(600, 150), color=(0, 0, 0, 0))
draw = ImageDraw.Draw(text)
draw.text((0, 0), 'OXXO.STUDIO', fill=(255, 255, 255), font=font) # 畫入文字
text = text.rotate(30, expand=1) # 旋轉這張圖片,expand 設定 1 表示展開旋轉,不要裁切
img.paste(text, (50, 0), text) # 將文字的圖片貼上原本的圖
img.save('./ok.jpg')
調整文字浮水印透明度
由於 PIL 裡調整透明度的 putalpha 方法,會調整 RGBA 裡的 A ( alpha ) 色版數值,如果作為浮水印本身是去背的圖片,會造成去背的部分也受到影響 ( 因為去背位置的像素包含了 alpha 資訊 ),因此如果要做到半透明的浮水印,可以先產生一張完全不透明的圖 ( 有浮水印的 ),然後再調整這張圖的透明度,與原本沒有浮水印的圖結合,就會產生半透明的浮水印效果。
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks') # Colab 換路徑使用
from PIL import Image, ImageFont, ImageDraw
# import os
img = Image.open('./photo.jpg')
w, h = img.size
font = ImageFont.truetype('Teko-Regular.ttf', 150)
text = Image.new(mode='RGBA', size=(600, 150), color=(0, 0, 0, 0))
draw = ImageDraw.Draw(text)
draw.text((0, 0), 'OXXO.STUDIO', fill=(255, 255, 255), font=font)
text = text.rotate(30, expand=1)
img2 = Image.open('./photo.jpg') # 再次開啟原本的圖為 img2
img2.paste(text, (50, 0), text) # 將文字貼上 img2
img2.convert('RGBA') # 圖片轉換為 RGBA 模式 ( 才能調整 alpha 色版 )
img2.putalpha(100) # 調整透明度,範圍 0~255,0 為全透明
img.paste(img2, (0, 0), img2) # 將 img2 貼上 img
img.save('./ok.jpg')
搭配 glob,批次加浮水印
了解加入浮水印的方法後,使用 glob 標準函式庫讀取 demo 資料夾裡所有的 jpg 檔案,就能批次加入浮水印。
- 參考:for 迴圈、拆分字串 split
- 圖片來源:爬取並自動下載 PTT 正妹圖片
from PIL import Image, ImageFont, ImageDraw
# import os
# os.chdir('/content/drive/MyDrive/Colab Notebooks') # Colab 換路徑使用
imgs = glob.glob('./demo/*.jpg') # 讀取 demo 資料夾裡所有的圖片
for i in imgs:
name = i.split('/')[::-1][0] # 取得圖片名稱
img = Image.open(i) # 開啟圖片
w, h = img.size
font = ImageFont.truetype('Teko-Regular.ttf', 100)
text = Image.new(mode='RGBA', size=(400, 100), color=(0, 0, 0, 0))
draw = ImageDraw.Draw(text)
draw.text((0, 0), 'OXXO.STUDIO', fill=(255, 255, 255), font=font)
text = text.rotate(30, expand=1)
img2 = Image.open(i)
img2.paste(text, (50, 0), text)
img2.convert('RGBA')
img2.putalpha(150)
img.paste(img2, (0, 0), img2)
img.save(f'./test/{name}')
小結
其實加浮水印的原理都大同小異,不外乎就是將「兩張圖片重疊」,透過程式的方式,就能夠一次將浮水印加入大量的圖片,省去不少人工作業的時間。
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~