Py学习  »  Python

Python 批量加水印!轻松搞定!

Python爱好者社区 • 3 年前 • 307 次点击  

转自:小一的学习笔记

想必有读者会遇到这种情况:自己辛辛苦苦写的文章被盗,而且对方在文章中既不显示原文链接,也不做任务说明,堂而皇之的自己标记“原创”

碰见这种事情,搁谁都会拍案而起。如果对方有良知的话你私信过去他可能会修改或者删文,可是要是对方不讲武德,那可真的太TM烦人了。

小一刚开始写文章的时候也有遇到过被抄袭,但是对方经不过我站在道德高点上的炮火猛击,后来就默默删文了

今天呢,小一教你们如何预防被抄袭,用 Python 给文章中的图片加水印!

水印应该都不陌生吧,一般像微博图片、微信文章的图片右下角都会有一个作者的 ID,更难一点的会在图片的某个随机部位有一个斜放的作者 ID

比如下面这个图,右下角的是原作者的水印 ID,图片中斜着的是我用 Python 添加的水印 ID


ok,下面来看一下如何用 Python 进行水印的添加

用 Python 进行水印的添加总共需要三步

  • 生成一张透明的水印
  • 将水印添加到一张空白图片上生成水印背景
  • 将水印背景粘贴到原图对应的位置上去

一般我们生成水印可以选择两种方式:固定位置的水印和全屏水印

类似微博照片那种一般会在图片的右下角、图片中间等部位添加水印标识,比较简单,也容易被去水印。

全屏水印就像上图中那种,会在很多很多位置生成水印标识,一般会在付费文档中使用,很难被去掉。

对了,说明一下,今天的文章源码绝大多数来源于 github 上的一个开源作者,小一在他的基础上进行了一些改进,使得初学者看起来会更容易理解!!

github 链接会在文末贴出来,小一修改后的源码也会在文末贴出来。

开始之前,我们需要明确以下参数含义,分别是:

dirpath_input = 'pic_bg'            # 图像路径
filepath_output = 'out/'            # 输出水印图像的文件夹,如果没有则在当前目录下主动创建
mark_content = '小一的学习笔记'        # 水印内容,默认是 "小一的学习笔记"。可不设置
mark_color = '#232862'              # 水印颜色,默认是 #232862【灰色】。可不设置
mark_space = 75                     # 水印之间的空隙,默认值为 75。可不设置
mark_angle = 30                     # 水印的角度,默认是 30°。可不设置
mark_size = 35                      # 水印字体的大小,默认是 50。可不设置
mark_opacity = 0.15                 # 水印透明度,默认是 0.05,数值越小越透明。可不设置
mark_quality = 90                   # 图片输出质量,默认是。可不设置
【左右滑动查看更多】


首先,生成一张透明的水印

这一步需要设置好水印的字体和内容,调用 Image 函数创建一张有关字体内容的透明水印

字体越大、内容越多,这个透明水印就越大,道理应该都懂。

代码如下:

# 字体宽度
width = len(mark_content) * mark_size
# 创建水印图片(宽度、高度)
mark = Image.new(mode='RGBA', size=(width, mark_size))

之后添加水印文字,设置水印透明度,裁剪图片的空白部分

水印字体的大小默认是 50。

水印透明度默认是 0.05,数值越小越透明。

代码如下:

# 生成文字
draw_table = ImageDraw.Draw(im=mark)
draw_table.text(xy=(0, 0), text=mark_content, fill=mark_color, font=ImageFont.truetype(TTF_FONT, size=mark_size))
del draw_table
# 裁剪空白
mark = crop_image(mark)
# 透明度
set_opacity(mark, mark_opacity)

字体 35,内容:小一的学习笔记,生成的水印图片是这样的:


其次,将水印添加到一张空白图片上生成水印背景

调用 Image 函数创建一张背景图片,如果是固定位置水印那只需要创建和原图同样大小的背景图片,如果是全屏水印那需要根据原图的对角线 C 生成一张 C*C 的背景图片

全屏水印一般需要设置倾角,所以最好设置大一点,对角线正好合适

全屏水印代码如下:

# 计算斜边长度
c = int(math.sqrt(im.size[0]*im.size[0] + im.size[1]*im.size[1]))
"""创建满屏的水印"""
# 以斜边长度为宽高创建大图(旋转后大图才足以覆盖原图)
mark2 = Image.new(mode='RGBA', size=(c, c))
y, idx = 00
while y     x = -int((mark.size[0] + mark_space)*0.5*idx)
    idx = (idx + 1) % 2

    while x         mark2.paste(mark, (x, y))
        x = x + mark.size[0] + mark_space
        y = y + mark.size[1] + mark_space

# 将大图旋转一定角度
mark2 = mark2.rotate(mark_angle)

特定位置的水印需要设置相应的图片坐标,具体的在代码 get_mark_style 函数可以设置常见的几种水印:水平居中、顶部居中、底部居中、底部靠左、底部靠右

相比在特定位置生成水印代码就简单很多:

# 创建一模一样的原图并添加水印
mark2 = Image.new(mode='RGBA', size=(im.size[0], im.size[1]))
x, y = get_mark_style(im, mark, "")
mark2.paste(mark, (x, y))

生成的水印背景图分别如下:

水印背景都是透明的,为了更清晰的体现底色加了深色背景

左边为全局水印,右边为水平居中水印】

最后,将水印背景粘贴到原图对应的位置上去

这一步很简单,只需要设置好粘贴的位置,将水印背景粘贴到原图上就行了。

如果是特定位置水印,因为水印背景和原图一样大,位置设成(0,0)即可;全局水印的话需要根据对角线选择位置,示例中的水印根据原图 (0,0) 点需要设置成 (-230,-114),大致就是下图所示

相应的代码为:

# 在原图上添加大图水印
if im.mode != 'RGBA':
    im = im.convert('RGBA')
# 全局水印设置
im.paste(mark2, (int((im.size[0]-c)/2), int((im.size[1]-c)/2)),  mask=mark2.split()[3])
# 特定位置水印设置
im.paste(mark2, (00), mask=mark2.split()[3])

到此,水印的添加就结束了,最终我们通过全局水印和特征位置水印的水印图分别是:

左边为全局水印,右边为底部居中水印】



写在后面的话

加水印是一种最简单的方式,但是稍微会 P 图的人都会轻松的把你的水印 P 掉,要是你觉得不影响观看体验,可以直接用全屏水印,就算他再不讲武德也很难轻松去掉全屏水印。

提到了去水印,大家有没有什么想法?


本节相关的代码可以在公众号 后台回复【加水印】 获取源码。

感兴趣的同学也可以去 github 上查看 2Dou 作者的源码,链接:https://github.com/2Dou/watermarker

感谢阅读

推荐阅读:

1真实的上海IT圈:张江男vs漕河泾男

2:真实的北京IT圈:后厂村姑 vs 后厂村花?

3:为什么你的提问没人解答?

4:Python爱好者社区历史文章合集



重磅!Python交流已成立


公众号运营至今,离不开小伙伴们的支持。
为了给小伙伴们提供一个互相交流的技术平台,特地开通了Python交流群。
群里有不少技术大神,不时会分享一些技术要点,更有一些资源收藏爱好者不时分享一些优质的学习资料。(免费,不卖课!)
需要进群的朋友,可长按扫描下方二维码。


▲长按扫码

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/106124
 
307 次点击