首页 > 技术文章 > python 批量添加图片水印

wangshx666 2021-01-30 09:44 原文

python程序,用来批量添加图片水印。输入一个文件夹、水印位置(左下角、底部中间、右下角)、用户名(用户名是中文的),批量给文件夹里所有的jpg和png图片在指定位置添加水印。
水印内容是:用户名 拍摄时间 拍摄地点。其中用户名是入参,拍摄时间和地点都从照片里读出来,如果读不出来拍摄时间的话就用文件最近修改时间代替,如果读不出来地点就留空。

'''
输入: 1.文件夹
      2.水印位置
      3.用户名
输出:1.用户名
      2.拍摄时间
      3.拍摄地点
'''

from PIL import Image, ImageDraw, ImageFont, ImageOps
import imghdr
import os
import exifread
import time as ostime



class AddWaterMark(object):
    def __init__(self, file_name, location, user):
        self.file_name = file_name
        self.location = location
        self.user = user

    # 防止图片发生旋转
    def exif_transpose(self, img):
        if not img:
            return img
        exif_orientation_tag = 274
        # Check for EXIF data (only present on some files)
        if hasattr(img, "_getexif") and isinstance(img._getexif(), dict) and exif_orientation_tag in img._getexif():
            exif_data = img._getexif()
            orientation = exif_data[exif_orientation_tag]

            if orientation == 1:
                pass
            elif orientation == 2:
                img = img.transpose(Image.FLIP_LEFT_RIGHT)
            elif orientation == 3:
                img = img.rotate(180)
            elif orientation == 4:
                img = img.rotate(180).transpose(Image.FLIP_LEFT_RIGHT)
            elif orientation == 5:
                img = img.rotate(-90, expand=True).transpose(Image.FLIP_LEFT_RIGHT)
            elif orientation == 6:
                img = img.rotate(-90, expand=True)
            elif orientation == 7:
                img = img.rotate(90, expand=True).transpose(Image.FLIP_LEFT_RIGHT)
            elif orientation == 8:
                img = img.rotate(90, expand=True)

        return img
    
    # 获取文件夹下的所有jpg、png图片
    def get_all_pic(self):
        imgType_list = {'jpg','bmp','png','jpeg','rgb','tif'}

        # imghdr 可以用来判断文件是否是图片
        for item in os.listdir(self.file_name):
            if os.path.isfile(item): 
                if imghdr.what(item) in imgType_list:
                    self.add_watermark_content(item)
    
    # 水印位置
    def get_watermark_location(self, img):
        width, height = img.size  # 图片大小
        fnt_size = max(width//50, height//50)  # 字体大小
        if self.location == '左下角':
            return (0, height-fnt_size*5)
        elif self.location == '右下角':
            return (width-fnt_size*12, height-fnt_size*5)
        else:  # 底部中间
            return (width//2-fnt_size*6, height-fnt_size*5)


    # 获取照片拍摄时间
    def get_pic_time(self, img_name):
        img = exifread.process_file(open(img_name,'rb'))
        if 'Image DateTime' in img.keys():
            time = img['Image DateTime']  # 拍摄时间
        else:
            file_path = os.path.join(self.file_name, img_name)
            time = ostime.ctime(os.stat(file_path).st_mtime)  #文件的修改时间 
        return time



    # 获取照片拍摄位置
    def get_pic_address(self, img_name):
        img = exifread.process_file(open(img_name,'rb'))
        if 'GPS GPSLatitude' in img.keys():
            latitude = img['GPS GPSLatitude']
        else:
            latitude = ''
        if 'GPS GPSLongitude' in img.keys():
            longitude = img['GPS GPSLongitude']
        else:
            longitude = ''
        position = f'{latitude}\n{longitude}\n'
        return position


    # 设置水印内容
    def set_content(self, img_name):
        user = self.user
        time = self.get_pic_time(img_name)
        position = self.get_pic_address(img_name)
        content = f'{user}\n{time}\n{position}\n'
        return content
    
    # 添加水印的内容
    def add_watermark_content(self, img_name):
        img = Image.open(img_name)
        # 防止图片发生旋转
        # if hasattr(ImageOps, 'exif_transpose'):
        #     img = ImageOps.exif_transpose(img)
        # else:
        #     img = self.exif_transpose(img)
        # img = img.convert('RGB')

        draw = ImageDraw.Draw(img)
        # 字体和大小
        fnt_size = max(img.size[0]//50, img.size[1]//50)
        font = ImageFont.truetype('C:\Windows\Fonts\simkai.ttf', size=fnt_size)
        # 水印位置
        (x,y) = self.get_watermark_location(img)
        # 水印内容
        content = self.set_content(img_name)
        # 位置,内容,字体,颜色,可以自行调节到合适
        draw.text((x,y), content, font=font, fill=(255, 255, 255))
        draw.text((x+2, y+2), content, font=font, fill=(0, 0, 0))
        self.save_watermark_pic(img, img_name)


    # 保存水印图片
    def save_watermark_pic(self, img, img_name):
        new_file = os.path.join(self.file_name, '水印图片')
        if not os.path.exists(new_file):
            os.mkdir(new_file)
        img.save(os.path.join(new_file, img_name), quality=95)


if __name__ == "__main__":

    file_name = 'D:\Desktop\picture'  # 文件名称
    location = '左下角'  # 水印位置:左下角、底部中间、右下角
    user = '超级无敌奥特曼'  # 用户名
    WM = AddWaterMark(file_name, location, user)
    WM.get_all_pic()

    print('hello world...')

推荐阅读