python 實現圖片批量加入水印!pillow 入門實戰!


寫文章的時候可以設置是否添加水印。可是,有些圖片可能想加水印,有些不想加水印,該怎么辦呢?

配置環境

python3 + pillow

pip3 install pillow

引入庫

from PIL import Image, ImageSequence
import os
import random

效果預覽:

file

使用方法:

  1. 在腳本同目錄下添加水印圖片 logo.png
  2. 創建目錄 input 並在放入要添加水印的圖片
  3. 創建目錄 output 執行腳本 addlogo.py
  4. 結果輸出在 output 文件夾下

file

實現原理

水印圖片采集:

先讀取水印圖片的像素點信息和大小信息。去除透明度為0的像素,並修改透明度像素信息。

img_logo = Image.open("logo.png")
img_logo_width, img_logo_height = img_logo.size
img_logo_pixels = dict()
for w in range(img_logo_width):
    for h in range(img_logo_height):
        c = img_logo.getpixel((w,h))
        if c!=(0, 0, 0, 0):
            img_logo_pixels[(w, h)] = c[:3]+(125,)

混合顏色:

對每一個像素點采取顏色混合,其中c1是源圖片的像素點信息(r,g,b,a),c2是logo圖片像素點的信息。混合算法如下:

def blendPixel(c1,c2):
    a1=256-c2[3]
    a2=c2[3]-(a1*c2[3])/256.0
    a=a1+a2
    c=(int((a1*c1[0] + a2*c2[0])/a), int((a1*c1[1] + a2*c2[1])/a), int((a1*c1[2] + a2*c2[2])/a),int(a))
    return c

處理源 Image 對象:

隨機一個位置開始處理像素,具體代碼參考如下。

def dealOneImage(image,offX=None,offY=None):
    w, h = image.size
    offX = offX if offX else random.random();
    offY = offY if offY else random.random();
    #如果圖片尺寸小於水印圖片,不加水印
    if w>=img_logo_width and h>=img_logo_height:
        top = int((w - img_logo_width)*offX)
        left = int((h - img_logo_height)*offY)
        for p, c in img_logo_pixels.items():
            p_x = (p[0]+top)
            p_y = (p[1]+left)
            image_c = image.getpixel((p_x,p_y))
            if(isinstance(image_c, tuple) and len(image_c)>2):
                image.putpixel((p_x, p_y), blendPixel(image_c,c))
    return image;

處理單個文件:

對於 gif 文件先拆成一張一張圖片,在圖片上添加水印,最后再合成 gif 。對於其他格式的圖片文件可以多添加幾個水印。最后輸出保存到 output 文件夾下。

def dealOneFile(filePath):
    img_orign = Image.open(filePath)
    _,file_type = os.path.splitext(filePath)
    basename = os.path.basename(filePath)
    if file_type == '.gif':
        sequence = [];
        offX=random.random()
        offY=random.random()
        for f in ImageSequence.Iterator(img_orign):
            if len(sequence) % 2 == 0:
                offX=random.random()
                offY=random.random()
            sequence.append(dealOneImage(f.convert(),offX,offY))
        sequence[0].save(f'./output/{basename}', save_all=True, append_images=sequence[1:])
    else:
        image_out = (dealOneImage(img_orign))
        for x in range(1):
            image_out = (dealOneImage(image_out))
        image_out.save(f'./output/{basename}')

處理目錄:

對當前目錄下的文件做一個篩選,只選取圖片格式的文件。

def dealSrc(srcDir):
    picFiles = [os.path.join(srcDir,fn) for fn in os.listdir(srcDir) if fn.endswith(('.gif', '.jpg', '.png','.jpeg'))]
    for filePath in picFiles:
        dealOneFile(filePath)

小結

添加水印主要用了 python3 中的 pillow 庫來實現。 首先是讀取 logo 圖片信息,接着在隨機一個位置添加混合后的像素點信息,最后再保存起來。

其中,對於 gif 文件的處理是拆幀,再添加水印,最后再組合成一個 gif。這個只能對應比較小的 gif 文件處理,如果有更好的方法歡迎留言交流分享!


本文僅供個人學習交流使用,請勿用於其他用途!


參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM