使用python PIL庫批量對圖片添加水印的過程詳解
1 簡單引入
- 平常我們想給某些圖片添加文字水印,方法有很多,也有很多的工具可以方便的進(jìn)行;
- 今天主要是對
PIL
庫的應(yīng)用,結(jié)合Python
語言批量對圖片添加水??; - 這里需要注意的是圖片的格式,不能為JPG或JPEG,因為這兩種格式的圖片不支持透明度設(shè)置。
2 關(guān)于PIL
PIL
是Python
的一個圖像處理庫,支持多種文件格式;PIL
提供強(qiáng)大的圖像處理和圖形處理能力;- 可完成對圖像的縮放、裁剪、疊加以及圖像添加線條、圖像和文字等操作。
- 安裝的話,使用以下命令:
pip install Pillow
3 本文涉及的PIL的幾個類
模塊或類 | 說明 |
---|---|
image模塊 | 用于對圖像就行處理 |
ImageDraw | 2D圖像對象 |
ImageFont | 存儲字體 |
ImageEnhance | 圖像增強(qiáng) |
4 實現(xiàn)原理
本文主要目的是批量對某個文件夾下的圖片進(jìn)行添加水印,原理如下:
- 對水印內(nèi)容設(shè)置;
- 使用
Image
對象的open()
方法打開原始圖片; - 使用
Image
對象的new()
方法新建存儲水印圖片對象; - 使用
Image.Draw.Draw
對象的text()
繪制水印文字; - 使用
ImageEnhance
中的Brightness
中的enhance()
設(shè)置水印透明度。
5 實現(xiàn)過程
5.1 原始圖片
- 我們設(shè)置一個原始圖片的存儲目錄,比如:
F:\python_study\image\image01
這個文件夾中存放了多個png
格式的圖片:
這里的一個原始圖片為:
5.2 導(dǎo)入相關(guān)模塊
- 導(dǎo)入需要的幾個
PIL
中的模塊或類:
from PIL import Image, ImageDraw, ImageFont, ImageEnhance import os
5.3 初始化數(shù)據(jù)
- 我們這里預(yù)想的是,通過用戶自己手動輸入相關(guān)信息,比如圖片的存儲路徑,需要設(shè)置的水印文字,通過輸入的方式設(shè)置水印的位置,設(shè)置水印的透明度等;
class TestText(): def __init__(self): super(TestText, self).__init__() self.pic_path = input('圖片路徑:') self.pic_text = input('水印文字:') self.p_flag = int(input('水印位置(1:左上角,2:左下角,3:右上角,4:右下角,5:居中):')) self.a = float(input('水印透明度(0—1之間的1位小數(shù)):'))
5.4 水印字體設(shè)置
- 這里我們先看下
ImageFont.truetype
源碼:
def truetype(font=None, size=10, index=0, encoding="", layout_engine=None): """ Load a TrueType or OpenType font from a file or file-like object, and create a font object. This function loads a font object from the given file or file-like object, and creates a font object for a font of the given size. Pillow uses FreeType to open font files. On Windows, be aware that FreeType will keep the file open as long as the FreeTypeFont object exists. Windows limits the number of files that can be open in C at once to 512, so if many fonts are opened simultaneously and that limit is approached, an ``OSError`` may be thrown, reporting that FreeType "cannot open resource". A workaround would be to copy the file(s) into memory, and open that instead. This function requires the _imagingft service. :param font: A filename or file-like object containing a TrueType font. If the file is not found in this filename, the loader may also search in other directories, such as the :file:`fonts/` directory on Windows or :file:`/Library/Fonts/`, :file:`/System/Library/Fonts/` and :file:`~/Library/Fonts/` on macOS. :param size: The requested size, in pixels. :param index: Which font face to load (default is first available face). :param encoding: Which font encoding to use (default is Unicode). Possible encodings include (see the FreeType documentation for more information):
- 它的大意就是從系統(tǒng)中的字體庫中讀取字體;
- 那我們的系統(tǒng)字體在哪里呢?
- 系統(tǒng)字體在
C:\Windows\Fonts
如下:
- 我們隨便選一個自己喜歡的字體,復(fù)制下名字即可:
self.font = ImageFont.truetype("cambriab.ttf", size=35)
5.5 打開原始圖片并新建存儲對象
- 打開原始圖片,并轉(zhuǎn)換為
RGB
:
image = Image.open(img).convert('RGBA')
- 創(chuàng)建繪制對象:
new_img = Image.new('RGBA', image.size, (255, 255, 255, 0)) image_draw = ImageDraw.Draw(new_img)
5.6 計算圖片和水印的大小
- 圖片大?。?/li>
w, h = image.size
- 文字大?。?/li>
w1 = self.font.getsize(self.pic_text)[0] # 獲取字體寬度 h1 = self.font.getsize(self.pic_text)[1] # 獲取字體高度
5.7 選擇性設(shè)置水印文字
- 通過
if
語句來實現(xiàn):
if self.p_flag == 1: # 左上角 location = (0, 0) elif self.p_flag == 2: # 左下角 location = (0, h - h1) elif self.p_flag == 3: # 右上角 location = (w - w1, 0) elif self.p_flag == 4: # 右下角 location = (w - w1, h - h1) elif self.p_flag == 5: # 居中 location = (h/2, h/2)
5.8 繪制文字并設(shè)置透明度
- 繪制文字:
image_draw.text(location, self.pic_text, font=self.font, fill="blue")
- 設(shè)置透明度
transparent = new_img.split()[3] transparent = ImageEnhance.Brightness(transparent).enhance(self.a) new_img.putalpha(transparent) Image.alpha_composite(image, new_img).save(img)
5.9 遍歷獲取圖片文件并調(diào)用繪制方法
text_pic = TestText() try: file_list = os.listdir(text_pic.pic_path) for i in range(0, len(file_list)): filepath = os.path.join(text_pic.pic_path, file_list[i]) if os.path.isfile(filepath): filetype = os.path.splitext(filepath)[1] if filetype == '.png': text_pic.test_text(filepath) else: print("圖片格式有誤,無法添加水印,請使用png格式圖片") print('批量添加水印完成') except: print('輸入的文件路徑有誤,請檢查~~')
6 完整源碼
# -*- coding:utf-8 -*- # 作者:蟲無涯 # 日期:2023/11/21 # 文件名稱:test_text_pic.py # 作用:批量給圖片添加文字水印和圖片水印 # 聯(lián)系:VX(NoamaNelson) # 博客:https://blog.csdn.net/NoamaNelson from PIL import Image, ImageDraw, ImageFont, ImageEnhance import os class TestText(): def __init__(self): super(TestText, self).__init__() self.pic_path = input('圖片路徑:') self.pic_text = input('水印文字:') self.p_flag = int(input('水印位置(1:左上角,2:左下角,3:右上角,4:右下角,5:居中):')) self.a = float(input('水印透明度(0—1之間的1位小數(shù)):')) # 設(shè)置字體 self.font = ImageFont.truetype("cambriab.ttf", size=35) # 文字水印 def test_text(self, img): global location image = Image.open(img).convert('RGBA') new_img = Image.new('RGBA', image.size, (255, 255, 255, 0)) image_draw = ImageDraw.Draw(new_img) w, h = image.size # 圖片大小 w1 = self.font.getsize(self.pic_text)[0] # 字體寬度 h1 = self.font.getsize(self.pic_text)[1] # 字體高度 # 設(shè)置水印文字位置 if self.p_flag == 1: # 左上角 location = (0, 0) elif self.p_flag == 2: # 左下角 location = (0, h - h1) elif self.p_flag == 3: # 右上角 location = (w - w1, 0) elif self.p_flag == 4: # 右下角 location = (w - w1, h - h1) elif self.p_flag == 5: # 居中 location = (h/2, h/2) # 繪制文字 image_draw.text(location, self.pic_text, font=self.font, fill="blue") # 設(shè)置透明度 transparent = new_img.split()[3] transparent = ImageEnhance.Brightness(transparent).enhance(self.a) new_img.putalpha(transparent) Image.alpha_composite(image, new_img).save(img) if __name__ == "__main__": text_pic = TestText() try: file_list = os.listdir(text_pic.pic_path) for i in range(0, len(file_list)): filepath = os.path.join(text_pic.pic_path, file_list[i]) if os.path.isfile(filepath): filetype = os.path.splitext(filepath)[1] if filetype == '.png': text_pic.test_text(filepath) print('批量添加水印完成') except: print('輸入的文件路徑有誤,請檢查~~')
7 顯示效果
- 運行過程:
D:\Python37\python.exe F:/python_study/python_project/test_text_pic.py
圖片路徑:F:\python_study\image\image01
水印文字:@蟲無涯
水印位置(1:左上角,2:左下角,3:右上角,4:右下角,5:居中):1
水印透明度(0—1之間的1位小數(shù)):0.5
F:/python_study/python_project/test_text_pic.py:32: DeprecationWarning: getsize is deprecated and will be removed in Pillow 10 (2023-07-01). Use getbbox or getlength instead.
w1 = self.font.getsize(self.pic_text)[0] # 獲取字體寬度
F:/python_study/python_project/test_text_pic.py:33: DeprecationWarning: getsize is deprecated and will be removed in Pillow 10 (2023-07-01). Use getbbox or getlength instead.
h1 = self.font.getsize(self.pic_text)[1] # 獲取字體高度
批量添加水印完成
不同位置的水印效果:
居中效果:
以上就是使用python PIL庫批量對圖片添加水印的過程詳解的詳細(xì)內(nèi)容,更多關(guān)于python PIL庫圖片添加水印的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python?ModuleNotFoundError:?No?module?named?‘xxx‘可能的解決方
本文主要介紹了Python?ModuleNotFoundError:?No?module?named?‘xxx‘可能的解決方案大全,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧Chat?Gpt<BR>2023-07-07使用Python對網(wǎng)易云歌單數(shù)據(jù)分析及可視化
這篇文章主要介紹了使用Python對網(wǎng)易云歌單數(shù)據(jù)分析及可視化,本項目以數(shù)據(jù)采集、處理、分析及數(shù)據(jù)可視化為項目流程,需要的朋友可以參考下2023-03-03Python初學(xué)者需要注意的事項小結(jié)(python2與python3)
這篇文章主要介紹了Python初學(xué)者需要注意的事項小結(jié),包括了python2與python3的一些區(qū)別,需要的朋友可以參考下2018-09-09在Python的框架中為MySQL實現(xiàn)restful接口的教程
這篇文章主要介紹了在Python的框架中為MySQL實現(xiàn)restful接口的教程,文中的示例基于Flask和Django框架,需要的朋友可以參考下2015-04-04利用Django-environ如何區(qū)分不同環(huán)境
這篇文章主要給大家介紹了關(guān)于利用Django-environ如何區(qū)分不同環(huán)境的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用django具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08