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 的安装过程 https://www.jianshu.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阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容