Python應用之批量打水印

之前寫菲律賓游記,想給自己的照片批量打上水印,首先想到的就是用Python實現給圖片加文字,然后寫個循環。

做過圖像識別的,應該知道OpenCV,其中cv2.putText()函數,就可以實現在圖片上加文字,非常簡單。

putText(img, text, org, fontFace, fontScale, color, thickness, lineType, bottomLeftOrigin)

參數解釋:

img:需要添加文字的圖片。
text:要加的文字內容。
org:文字的位置坐標。
fontFace:字體類型(可選擇字體有限,可設置斜體)。
fontScale:字體大小。
color:字體顏色。
thickness:字體粗細。
lineType:線型。
bottomLeftOrigin:默認值為false,圖片數據原點在左上角。

但putText()有個問題,不能添加中文文字,也不能指定字體,而PIL(Python Image Library)可以解決這個問題。


Image模塊

Image是PIL中的核心模塊,實現對圖片的基礎操作。

Image中的函數:

  1. Image. open(path):打開現成的圖片,該圖片在path所示的路徑中。

  2. Image. new(mode, size, color):創建新的圖片文件,color默認為黑色。

Image對象的屬性:

  1. image.format:查看圖像的格式,常見的有JPG、PNG等。

  2. image.mode:查看圖像的模式。常用的例如RGB,3x8位像素,為真彩色;RGBA,4x8位像素,有透明通道的真彩色。

  3. image.size:獲取圖片的尺寸(長×寬),該二元組也表示圖片的像素。

import os
import sys
from PIL import Image, ImageFont, ImageDraw

# 讀入要打水印的照片
image = Image.open('./input/IMG_1422.jpg')
im_size = image.size

print(image.format)
print(image.mode)
print(im_size)
image.show()

----------------------
[out] JPEG
[out] RGB
[out] (1536, 2048)

原始照片:


錫島拉孜教堂


ImageDraw模塊

ImageDraw模塊,提供對圖像進行繪制的方法。

  1. ImageDraw.Draw(image):創建畫刷。

  2. ImageFont.truetype(file, size) :設置字體和大小,file提供字體的路徑,size為文字大小。在C盤(系統盤)-Windows-Fonts里面,有計算機上安裝的所有字體,選一個喜歡的。

  3. draw.text(xy, text, fill, font):根據位置、內容、顏色、字體把文字寫進圖片中。
    xy:位置,即距離圖片左上角起始點的坐標。
    這里普及一下圖片坐標系統的概念。
    圖片坐標常用二元組(x,y),(0,0)位于左上角。
    四元組表示圖片左、上、右、下的坐標,例如800x600像素的長方形圖片表示為(0,0,800,600)。
    text:字符串,即文字內容。
    fill:文字顏色。
    font:字體和大小,通過上述ImageFont來定義。

用draw.text()加水印文字,特別簡單!

########### 加文字 ###########
draw_txt = ImageDraw.Draw(image)
txt_size = int(im_size[0]*0.02)

# 設置字體和文字大小
chi_font = ImageFont.truetype('./font/fzstk.ttf', size=txt_size)

# 直接在照片上寫文字
draw_txt.text(xy = (im_size[0]//2-txt_size//2,im_size[1]-int(txt_size*1.2)),
              text = '@化簡可得',
              font = chi_font)

image.show()
打上水印后


Image中的方法

  1. image.show():展示圖像,Win系統下show會打開系統自帶的圖像顯示程序。
  2. image.transpose(method):圖像翻轉或者旋轉,例如ROTATE_90表示將圖像逆時針旋轉90°。
  3. image. thumbnail (size):制作縮略圖,參數size指定最大的寬度和高度。
  4. image.paste(region, box, mask):將一張圖粘貼到另一張圖上。
    image:底圖;
    region:要粘貼上底圖的圖,即水印圖片;
    box:要粘貼的位置,2元組表示左上角坐標;
    mask:對應的模板圖像來填充所對應的區域,模板圖像的尺寸必須與region對應的圖像尺寸一樣,原圖像和模板圖像可以為同一個圖。
  5. image. save(path, quality):針對JPG格式,quality參數表示保存圖像的質量,值的范圍從1(最差)到95(最佳)。 默認值為75,此時圖片會被壓縮。

用image.paste()加水印圖,也特別簡單!

########### 加圖片 ###########
# 讀入水印圖
# 還沒設計過自己的水印logo,所以隨便在網上找了一個小太陽做示范
mark_image = Image.open('./sun.png')

# 這個小太陽有點大,壓縮一下
mark_image.thumbnail((150, 150)) 

# 將小太陽加在照片左上角的位置
position = mark_size//3, mark_size//3 
image.paste(mark_image, position, mark_image)

image.show()
錫基霍爾島上的COCO度假村一隅


小結

新建watermark文件夾,該文件夾下放入Python文件,并新建3個子文件夾:

  1. font文件夾存放字體;
  2. input存放原始圖片;
  3. output文件夾為空,程序跑完后打好水印的圖片會輸出到該文件夾。

背景水印打法可以看這篇https://zhuanlan.zhihu.com/p/138732523

水印效果

route.png

python marker.py -f ./input -m 化簡可得 -c #232862 --opacity 0.08 -s 200 --size 100


跑批代碼,下面自取~

########## 批量加水印文字 #########
import os
import sys
from PIL import Image, ImageFont, ImageDraw

def add_watermark(image_file): 
    image = Image.open(image_file)
    draw_txt = ImageDraw.Draw(image)
    
    im_size = image.size
    print('原始圖片尺寸:',im_size)
    if im_size[0]>im_size[1]: #如果是橫版
        txt_size = int(im_size[0]*0.02)
    else:
        txt_size = int(im_size[1]*0.02)
    print('水印文字尺寸:',txt_size)
    
    # 設置字體和文字大小
    chi_font = ImageFont.truetype('./font/fzstk.ttf', size=txt_size)

    # 直接在照片上寫文字
    draw_txt.text(xy = (im_size[0]//2-txt_size//2, im_size[1]-int(txt_size*1.2)),
                  text = '@化簡可得',
                  font = chi_font)
          
    name = os.path.basename(image_file)
    new_name = os.path.join('.\output', name)
    image.save(new_name, quality=95)
    
### 循環讀入照片
files = os.listdir('.\input')
for file in files:
    image_file = os.path.join('.\input', file)
    print(image_file)
    add_watermark(image_file)


########## 批量加水印照片 #########
import os
import sys
from PIL import Image, ImageFont, ImageDraw

# 讀入水印圖
mark_image = Image.open('./sun.png')

def add_watermark(image_file): 
    image = Image.open(image_file)    
    im_size = image.size
    print('原始圖片尺寸:',im_size)
    
    if im_size[0]>im_size[1]: #如果是橫版
        mark_size = int(im_size[0]*0.08)
    else:
        mark_size = int(im_size[1]*0.08)

    mark_image.thumbnail((mark_size, mark_size))
    print('水印圖片尺寸:',mark_image.size)

    position = mark_size//3, mark_size//3
    image.paste(mark_image, position, mark_image)
    
    name = os.path.basename(image_file)
    new_name = os.path.join('.\output', name)
    image.save(new_name, quality=95)

# 循環讀入照片
files = os.listdir('.\input')
for file in files:
    image_file = os.path.join('.\input', file)
    print(image_file)
    add_watermark(image_file)

當然,網上有很多現成的軟件,也能實現批量打水印。但我還是喜歡用Python,以后想要什么樣的效果,改改參數就好了~


參考鏈接

  1. Win10 + Opencv3 for Python 的安裝過程 http://www.lxweimin.com/p/c3af3cadf372

  2. Py之cv2:cv2庫的簡介、安裝、使用方法(常見函數、方法等)最強詳細攻略
    https://blog.csdn.net/qq_41185868/article/details/79675875#%E5%85%B3%E4%BA%8EOpenCV%E7%AE%80%E4%BB%8B

  3. python PIL 圖像處理庫簡介(一) https://www.cnblogs.com/lyrichu/p/9124504.html

  4. python PIL的Image.resize()和Image.thumbnail()函數的區別
    https://blog.csdn.net/TeFuirnever/article/details/90597048

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,401評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,011評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,263評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,543評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,323評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,874評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,968評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,095評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,605評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,551評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,720評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,242評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,961評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,358評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,612評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,330評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,690評論 2 370

推薦閱讀更多精彩內容