欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python實現(xiàn)圖像添加水印的方法

 更新時間:2024年07月12日 08:35:14   作者:王二空間  
在日常圖像處理中,為圖片添加水印是一項常見任務,本文主要介紹了Python實現(xiàn)圖像添加水印的方法,具有一定的參考價值,感興趣的可以了解一下

1. 簡介

在日常圖像處理中,為圖片添加水印是一項常見任務。有多種方法和工具可供選擇,而今天我們將專注于使用Python語言結合PIL庫批量添加水印。

需要注意的是,所選用的圖片格式不應為JPG或JPEG,因為這兩種格式的圖片不支持透明度設置。

2. PIL庫概述

  • PIL是Python的圖像處理庫,支持多種文件格式。
  • PIL提供強大的圖像和圖形處理功能,包括縮放、裁剪、疊加以及添加線條、文字等操作。
  • 安裝PIL庫可使用以下命令:
pip install Pillow

3. PIL庫中涉及的類

模塊或類說明
image模塊用于圖像處理
ImageDraw2D圖像對象
ImageFont字體存儲
ImageEnhance圖像增強

4. 實現(xiàn)原理

本文的主要目標是批量為某個文件夾下的圖片添加水印,實現(xiàn)原理如下:

  • 設置水印內容;
  • 使用Image對象的open()方法打開原始圖片;
  • 使用Image對象的new()方法創(chuàng)建存儲水印圖片的對象;
  • 使用ImageDraw.Draw對象的text()方法繪制水印文字;
  • 使用ImageEnhance中Brightness的enhance()方法設置水印透明度。

5. 實現(xiàn)過程

5.1 原始圖片

設定原始圖片的存儲目錄,例如:

F:\python_study\image\image01

5.2 導入相關模塊

導入所需的PIL模塊或類:

from PIL imort Image, ImageDraw, ImageFont, ImageEnhance
import os

5.3 初始化數(shù)據(jù)

通過用戶手動輸入相關信息,如圖片存儲路徑、水印文字、水印位置、水印透明度等:

class WatermarkText():
    def __init__(self):
        super(WatermarkText, self).__init__()
        self.image_path = input('圖片路徑:')
        self.watermark_text = input('水印文字:')
        self.position_flag = int(input('水印位置(1:左上角,2:左下角,3:右上角,4:右下角,5:居中):'))
        self.opacity = float(input('水印透明度(0—1之間的1位小數(shù)):'))

5.4 水印字體設置

選擇系統(tǒng)字體庫中的字體:

self.font = ImageFont.truetype("cambriab.ttf", size=35)

5.5 打開原始圖片并創(chuàng)建存儲對象

打開原始圖片并轉換為RGBA:

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 計算圖片和水印的大小

計算圖片大小:

w, h = image.size

計算文字大?。?/p>

w1 = self.font.getsize(self.watermark_text)[0]
h1 = self.font.getsize(self.watermark_text)[1]

5.7 選擇性設置水印文字

通過if語句實現(xiàn):

if self.position_flag == 1:  # 左上角
    location = (0, 0)
elif self.position_flag == 2:  # 左下角
    location = (0, h - h1)
elif self.position_flag == 3:  # 右上角
    location = (w - w1, 0)
elif self.position_flag == 4:  # 右下角
    location = (w - w1, h - h1)
elif self.position_flag == 5:  # 居中
    location = (h/2, h/2)

5.8 繪制文字并設置透明度

繪制文字:

image_draw.text(location, self.watermark_text, font=self.font, fill="blue")

設置透明度:

transparent = new_img.split()[3]
transparent = ImageEnhance.Brightness(transparent).enhance(self.opacity)
new_img.putalpha(transparent)

Image.alpha_composite(image, new_img).save(img)

5.9 遍歷獲取圖片文件并調用繪制方法

watermark_text = WatermarkText()
try:
    file_list = os.listdir(watermark_text.image_path)
    for i in range(0, len(file_list)):
        filepath = os.path.join(watermark_text.image_path, file_list[i])
        if os.path.isfile(filepath):
            filetype = os.path.splitext(filepath)[1]
            if filetype == '.png':
                watermark_text.add_text_watermark(filepath)
            else:
                print("圖片格式有誤,請使用png格式圖片")
    print('批量添加水印完成')
except:
    print('輸入的文件路徑有誤,請檢查~~')

6. 完整源碼

from PIL import

 Image, ImageDraw, ImageFont, ImageEnhance
import os

class WatermarkText():
    def __init__(self):
        super(WatermarkText, self).__init__()
        self.image_path = input('圖片路徑:')
        self.watermark_text = input('水印文字:')
        self.position_flag = int(input('水印位置(1:左上角,2:左下角,3:右上角,4:右下角,5:居中):'))
        self.opacity = float(input('水印透明度(0—1之間的1位小數(shù)):'))

        # 設置字體
        self.font = ImageFont.truetype("cambriab.ttf", size=35)

    # 文字水印
    def add_text_watermark(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.watermark_text)[0]  # 字體寬度
        h1 = self.font.getsize(self.watermark_text)[1]  # 字體高度

        # 設置水印文字位置
        if self.position_flag == 1:  # 左上角
            location = (0, 0)
        elif self.position_flag == 2:  # 左下角
            location = (0, h - h1)
        elif self.position_flag == 3:  # 右上角
            location = (w - w1, 0)
        elif self.position_flag == 4:  # 右下角
            location = (w - w1, h - h1)
        elif self.position_flag == 5:  # 居中
            location = (h/2, h/2)
        # 繪制文字
        image_draw.text(location, self.watermark_text, font=self.font, fill="blue")

        # 設置透明度
        transparent = new_img.split()[3]
        transparent = ImageEnhance.Brightness(transparent).enhance(self.opacity)
        new_img.putalpha(transparent)

        Image.alpha_composite(image, new_img).save(img)

if __name__ == "__main__":
    watermark_text = WatermarkText()
    try:
        file_list = os.listdir(watermark_text.image_path) 
        for i in range(0, len(file_list)): 
            filepath = os.path.join(watermark_text.image_path, file_list[i])
            if os.path.isfile(filepath): 
                filetype = os.path.splitext(filepath)[1] 
                if filetype == '.png': 
                    watermark_text.add_text_watermark(filepath) 
                else:
                    print("圖片格式有誤,請使用png格式圖片")
        print('批量添加水印完成')
    except:
        print('輸入的文件路徑有誤,請檢查~~')

7. 效果展示

運行過程:

D:\Python37\python.exe F:/python_study/python_project/watermark_text.py
圖片路徑:F:\python_study\image\image01
水印文字:
水印位置(1:左上角,2:左下角,3:右上角,4:右下角,5:居中):1
水印透明度(0—1之間的1位小數(shù)):0.5
F:/python_study/python_project/watermark_text.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.watermark_text)[0]  # 獲取字體寬度
F:/python_study/python_project/watermark_text.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.watermark_text)[1]  # 獲取字體高度
批量添加水印完成

8. 改進與建議

8.1 參數(shù)輸入方式優(yōu)化

在初始化數(shù)據(jù)的部分,我們可以考慮通過命令行參數(shù)或配置文件的方式輸入相關信息,以提高用戶體驗。例如使用argparse庫來解析命令行參數(shù)。

import argparse

class WatermarkText():
    def __init__(self):
        parser = argparse.ArgumentParser(description='Add watermark to images.')
        parser.add_argument('--image_path', type=str, help='Path to the image directory.')
        parser.add_argument('--watermark_text', type=str, help='Text for watermark.')
        parser.add_argument('--position_flag', type=int, help='Position flag for watermark (1: top-left, 2: bottom-left, 3: top-right, 4: bottom-right, 5: center).')
        parser.add_argument('--opacity', type=float, help='Opacity for watermark (0-1 with 1 decimal place).')
        
        args = parser.parse_args()

        self.image_path = args.image_path or input('Image path: ')
        self.watermark_text = args.watermark_text or input('Watermark text: ')
        self.position_flag = args.position_flag or int(input('Watermark position (1: top-left, 2: bottom-left, 3: top-right, 4: bottom-right, 5: center): '))
        self.opacity = args.opacity or float(input('Watermark opacity (0-1 with 1 decimal place): '))

8.2 異常處理改進

在處理異常的部分,我們可以更具體地捕獲異常類型,并提供更友好的提示信息。

try:
    # existing code...
except FileNotFoundError:
    print('Error: The specified image directory does not exist.')
except PermissionError:
    print('Error: Permission denied to access the specified image directory.')
except Exception as e:
    print(f'An unexpected error occurred: {e}')

8.3 代碼結構優(yōu)化

可以考慮將一些功能模塊化,提高代碼的可讀性和維護性。例如,將文字水印的添加功能獨立成一個方法。

class WatermarkText():
    # existing code...

    def add_text_watermark(self, img):
        # existing code...

8.4 日志記錄

考慮在程序中添加日志記錄,記錄關鍵步驟和出錯信息,以便于排查問題。

import logging

logging.basicConfig(level=logging.INFO)

class WatermarkText():
    # existing code...

    def add_text_watermark(self, img):
        try:
            # existing code...
            logging.info(f'Successfully added watermark to {img}')
        except Exception as e:
            logging.error(f'Error adding watermark to {img}: {e}')

8.5 擴展功能

在程序中可以考慮添加更多功能,比如支持不同的水印顏色、字體大小等選項,以使程序更加靈活。

這些改進和建議將有助于提高程序的穩(wěn)定性、易用性和可維護性。

當然,我們將繼續(xù)改進和完善你的代碼。在這一部分,我們會考慮一些進一步的優(yōu)化和改進。

9. 優(yōu)化圖片格式檢查

在處理圖片文件時,可以優(yōu)化檢查圖片格式的方式。使用os.path.splitext得到的文件擴展名可能包含大寫字母,為了確保匹配,可以將文件擴展名轉換為小寫。

if filetype.lower() == '.png':
    watermark_text.add_text_watermark(filepath)
else:
    print("Error: Image format is not supported. Please use PNG format.")

10. 增加用戶交互性

可以考慮在程序中增加更多用戶交互性,比如在成功添加水印后詢問用戶是否繼續(xù)添加水印。

while True:
    try:
        # existing code...

        print('Watermark added successfully.')
        
        another = input('Do you want to add watermark to another image? (yes/no): ').lower()
        if another != 'yes':
            break
    except Exception as e:
        logging.error(f'Error: {e}')

這樣,用戶可以選擇是否繼續(xù)添加水印,提高程序的交互性。

11. 多線程處理

如果你需要處理大量圖片,可以考慮使用多線程來加速處理過程。這可以通過concurrent.futures模塊實現(xiàn)。

from concurrent.futures import ThreadPoolExecutor

# existing code...

if __name__ == "__main__":
    watermark_text = WatermarkText()
    try:
        file_list = os.listdir(watermark_text.image_path) 

        with ThreadPoolExecutor() as executor:
            executor.map(watermark_text.add_text_watermark, [os.path.join(watermark_text.image_path, file) for file in file_list])

        print('Batch watermarking completed.')
    except Exception as e:
        logging.error(f'Error: {e}')

這將允許同時處理多個圖片,提高處理速度。

12. 其他優(yōu)化建議

  • 考慮支持更多圖片格式,而不僅限于PNG。你可以使用Pillow庫中的Image.register_open()方法注冊其他格式的圖片打開器。
  • 如果水印文字較長,可以考慮自動調整文字大小,以適應圖片。

到此這篇關于Python實現(xiàn)圖像添加水印的方法的文章就介紹到這了,更多相關Python 圖像添加水印內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家! 

相關文章

  • python批量修改文件名的三種方法實例

    python批量修改文件名的三種方法實例

    同事最近有個需求,需要批量修改文件的名稱,這篇文章主要給大家介紹了關于python批量修改文件名的三種方法,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-05-05
  • python圖片驗證碼識別最新模塊muggle_ocr的示例代碼

    python圖片驗證碼識別最新模塊muggle_ocr的示例代碼

    這篇文章主要介紹了python圖片驗證碼識別最新模塊muggle_ocr的相關知識,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • 對Xpath 獲取子標簽下所有文本的方法詳解

    對Xpath 獲取子標簽下所有文本的方法詳解

    今天小編就為大家分享一篇對Xpath 獲取子標簽下所有文本的方法詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • 使用Python和GDAL給圖片加坐標系的實現(xiàn)思路(坐標投影轉換)

    使用Python和GDAL給圖片加坐標系的實現(xiàn)思路(坐標投影轉換)

    這篇文章主要介紹了使用Python和GDAL給圖片加坐標系的實現(xiàn)思路(坐標投影轉換),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • Python的Import機制的模塊與包深入理解

    Python的Import機制的模塊與包深入理解

    深入理解Python的import機制有助于更好地組織代碼、提高代碼復用性,本文將深入研究Python的Import機制,包括模塊的導入過程、命名空間與作用域、相對導入以及包的結構和導入等方面,通過豐富的示例代碼,助你更全面地理解和應用這
    2024-01-01
  • Node.js 和 Python之間該選擇哪個?

    Node.js 和 Python之間該選擇哪個?

    這篇文章主要介紹了Node.js 和 Python之間的優(yōu)劣,并得出結論,希望能為你在項目選擇哪種技術時提供一些幫助。感興趣的朋友可以了解下
    2020-08-08
  • python str字符串轉uuid實例

    python str字符串轉uuid實例

    這篇文章主要介紹了python str字符串轉uuid實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • Python利用request庫實現(xiàn)翻譯接口

    Python利用request庫實現(xiàn)翻譯接口

    這篇文章主要為大家詳細介紹了Python如何利用request庫打造自己的翻譯接口,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-04-04
  • python中數(shù)組array和列表list的基本用法及區(qū)別解析

    python中數(shù)組array和列表list的基本用法及區(qū)別解析

    大家都知道數(shù)組array是同類型數(shù)據(jù)的有限集合,列表list是一系列按特定順序排列的元素組成,可以將任何數(shù)據(jù)放入列表,且其中元素之間沒有任何關系,本文介紹python中數(shù)組array和列表list的基本用法及區(qū)別,感興趣的朋友一起看看吧
    2022-05-05
  • Python基礎文件操作方法超詳細講解(詳解版)

    Python基礎文件操作方法超詳細講解(詳解版)

    文件就是操作系統(tǒng)為用戶或應用程序提供的一個讀寫硬盤的虛擬單位,文件的核心操作就是讀和寫,這篇文章主要介紹了Python基礎文件操作方法超詳細講解的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-04-04

最新評論