水印工具制作

简介: 诱因原理图片水印文字水印完整代码使用方法help命令单张图片水印单张文字水印批量图片水印批量文字水印注意与拓展注意编码问题文字水印自适应拓展总结今天来分享一个自己做的实用工具,那就是为图片添加水印。

今天来分享一个自己做的实用工具,那就是为图片添加水印。最大的特点就是支持文字水印(可以为汉字,英文),也支持图片水印。既可以单张图片加水印,也可以支持批量图片加水印。

诱因

我本人平时喜欢写点博客什么的,所以不可避免的会使用贴图,然而目前(2016年11月27日)而言CSDN上还不能有效的为自己的图片自动的添加水印。所以这给那些爬取博客作为自己网站博客的网站提供了可乘之机。

比如: 自己在CSDN上的原创,却被其他占据了头条。
被人盗用

先不说自己的文章质量怎么样,无论好与坏,都是自己一个字母一个字母敲出来的,多少也有点苦劳。但是被别人不加声明的就弄走了,这就让人有点幽怨了。更有甚者,还会加上他们自己网站的水印,“成了他们原创的了”。··· ···

于是,为了给自己一个交代。决定写个小工具。自己给自己的图片添加水印,自己保护自己吧。

原理

图片水印

对图片水印而言,我们就可以这样理解:把一张图片粘贴到另一张图片上。只不过这是使用代码实现的罢了。

文字水印

文字水印稍微有点不太一样。但是原理上其实也是差不多的。那就是先使用PIL生成一张背景图,然后再这张图片上放上一些文字(对于汉字需要额外的做些处理)。最后使用图片水印的原理把这张生成的图片作为水印添加到另一张图片上。

完整代码

下面贴出完整代码,有需要的请自取。

# coding:utf-8
import sys

reload(sys)
sys.setdefaultencoding('utf8')
#    __author__ = '郭 璞'
#    __date__ = '2016/11/26'
#    __Desc__ = 单个,批量给图片添加水印,既可以使用文字水印,\
# 也可以使用图片水印(默认拥有更高的优先级,如果既指定文字,又指定图片,默认仅采用图片水印)

# 使用PIL操作图片
from PIL import Image, ImageFont, ImageDraw
# 获取路径下所有图片
import os
# 添加命令行参数
import argparse

# 使用水印图片作为原材料添加水印,需指定完整路径信息
def picmark(tomarkpath, markpath):
    image = Image.open(tomarkpath)
    mark = Image.open(markpath)
    layer = Image.new("RGBA", image.size, (0, 0, 0, 0))
    x, y = image.size[0]-mark.size[0]-12, image.size[1]-mark.size[1]-10
    layer.paste(mark, (x, y))
    out = Image.composite(layer, image, layer)
    out.save(tomarkpath)
    print "{} has beed added the watermark successfully :)".format(tomarkpath)

# 生成图片水印素材,以供使用。
def textgenerate(text='http://blog.csdn.net\nCSDN 郭 璞', textcolor=(0, 0, 0), bgcolor=(255, 255, 255)):
    # After test, those parameters is suitful for Chinese watermark.
    size = len(text) * 12, len(text) * 2
    fontsize = len(text) / 2  if len(text)/2 > 20 else 24

    font = ImageFont.truetype('simsun.ttc', fontsize)
    image = Image.new('RGB', size, bgcolor)
    draw = ImageDraw.Draw(image)
    draw.text((size[0] / 7, size[1] / 5), u'{}'.format(text), textcolor, font=font)
    # image.save(r'./asdsadsadsasa.png')
    return image

# 生成文字水印结果,需指定完整路径,第二个参数为生成的文字水印素材,地位相当于一个外部的水印图片。
def textmark(tomarkpath, markimage):
    image = Image.open(tomarkpath)
    layer = Image.new("RGBA", image.size, (0, 0, 0, 0))
    x, y = image.size[0] - markimage.size[0] - 12, image.size[1] - markimage.size[1] - 10
    layer.paste(markimage, (x, y))
    out = Image.composite(layer, image, layer)
    out.save(tomarkpath)
    print "{} has beed added the watermark successfully :)".format(tomarkpath)

# 获取指定路径下的所有图片,包括png,jpg, jpeg, gif等。可手动拓展。
def getallpics(dirpath):
    pics = []
    files = os.listdir(dirpath)
    for filename in files:
        if str(filename).endswith('jpeg') or str(filename).endswith('png') or str(filename).endswith('jpg') or str(filename).endswith('gif'):
            pics.append(filename)
        else:
            continue
    return pics

# 批量添加图片水印,默认添加在右下角位置
def runbatchlywithmark(markpath, dirpath):
    tomarkfiles = getallpics(dirpath=dirpath)
    watermarkname = markpath.split('/')[-1]
    tomarkfiles.remove(watermarkname)
    # print tomarkfiles
    for item in tomarkfiles:
        picmark(item, markpath)
    print "All done!"

# 批量添加文字水印,默认添加在图片右下角位置。会根据需求自动计算出合适大小的文字水印图片
def runbatchlywithtext(dirpath, text, textcolor=(85, 123, 205), bgcolor=(0,0,0)):
    tomarkfiles = getallpics(dirpath=dirpath)
    # print tomarkfiles
    markimage = textgenerate(text=text, textcolor=textcolor, bgcolor=bgcolor)
    for item in tomarkfiles:
        textmark(item, markimage)
    print "All done!"


# 主函数,完成所有业务逻辑处理
if __name__ == '__main__':

    # 声明相关命令行参数信息
    parser = argparse.ArgumentParser(description='Add watermark to your pictures batchly and singly!\n You can also assign the text color or background color.\n')
    parser.add_argument('-t', '--text', type=str, default='CSDN  郭 璞', help='the text you want to attach to the picture!')
    parser.add_argument('-tc', '--textcolor', type=str, default=(85, 123, 205), help='the text color you want!\n Both style like (85, 123, 205) and #XXXXXX can be all right')
    parser.add_argument('-bgc', '--bgcolor', type=str, default=(32, 234, 105),
                        help='the background color you want!\n Both style like (32, 234, 105) and #XXXXXX can be all right')
    parser.add_argument('-dp', '--dirpath', type=str, default=r'./', help='the directory contains pictures you want to attach watermark.\n Default directory is current directory.')
    parser.add_argument('-mp', '--markpath', type=str, help='the watermark picture you prepared already!\n Generally it\'s smaller than raw pictures.')
    parser.add_argument('-spp', '--singlepicpath', type=str, help='the single picture path you want to add watermark.')
    args = parser.parse_args()

    # Because of the codec in cmd on windows, utf-8 should be use carefully when attach Chinese text as watermark.
    text = args.text.decode('gbk').encode('utf-8')
    textcolor = args.textcolor
    bgcolor = args.bgcolor
    dirpath = args.dirpath
    markpath = args.markpath
    singlepicpath = args.singlepicpath

    # for single picture attaching watermark.
    if singlepicpath:
        # attach text or using mark picture prepared
        if markpath:
            picmark(tomarkpath=singlepicpath, markpath=markpath)
        else:
            markimage = textgenerate(text=text, textcolor=textcolor, bgcolor=bgcolor)
            textmark(tomarkpath=singlepicpath, markimage=markimage)
    else:
        # attach text or using mark picture prepared
        if markpath:
            runbatchlywithmark(markpath=markpath, dirpath=dirpath)
        else:
            runbatchlywithtext(dirpath=dirpath, text=text, textcolor=textcolor, bgcolor=bgcolor)

使用方法

由于使用了argparse,所以可以很方便的进行命令行参数的使用。如果有什么不懂,直接使用help命令即可。会有详细的使用方式输出。

help命令

help命令查看使用方法

单张图片水印

要添加图片水印,就需要事先准备好一张效果图了。比如博主准备了一张280X52像素大小的素材。
水印素材

那么为了演示方便,还得找一张要进行水印的图片才行。不妨使用下面的这张图片好了。
待加水印原图

那么正式开始咯。
单张图片水印

单张文字水印

好了,还是那张图片,这次尝试一下文字水印。
除了可以指定-t -tc, -bgc等选项。我们还可以使用默认值,虽然默认值是博主自己的信息,(^__^) 嘻嘻……

单张文字水印

批量图片水印

批量的其实就是把指定目录下的所有的要进行水印的图片添加了水印而已。
批量图片水印命令

然后在测试的文件夹下可以查看到,所有的图片(除了水印图片自身)都被添加了图片水印。
批量图片水印效果

批量文字水印

同理,下面将演示批量添加文字水印。
批量添加文字水印效果

相信图片右下角的绿色的标示已经很明显了吧。

注意与拓展

好了,说完了让人激动的条目。下面可以来聊聊这个工具存在的一些问题吧。

注意

编码问题

首先需要注意的仍然是老生常谈的Python中的编码问题了。默认Python脚本文件以UTF-8编码,而Windows的CMD命令行为GBK编码,所以输入汉字的时候Python解释器就会报错。解决的办法目前是采用硬编码的方式。

text = args.text.decode(‘gbk’).encode(‘utf-8’)

源码中有这么一行命令,就是为了将在CMD中输入的汉字转为UTF-8编码,让Python解释器可以正确的运行。

但是如果您的环境是Linux,那就不能这样写了。否则还是会报出解码异常问题的。
所以就需要您自己查看一下自己的环境的编码信息,然后对脚本进行硬编码处理。

或许,这个时候会有许多不服气的朋友要鼓吹Python3多么多么好了,其实我也不反对,但是个人觉得说这些,没有什么意义。语言是工具,每个人都可以有自己的喜好,没有谁非得按照你的意愿办事,管好自己就行了。题外话了,不多说了。

文字水印自适应

脚本中对于文字水印做了一点自适应的处理。但是还不够完善。有需要的话可以自行指定。

另外,文字水印字体大小同样可以进行处理。

拓展

我觉得除了针对上面的问题进行优化之外,还有一个比较大,也比较容易实现的方向。那就是水印位置。脚本中简单的按照博主自己的需求手动的指定为图片右下角了。这一点不是很有普适性。因此可以进一步对脚本进行拓展,以实现人以为会水印的添加。

总结

回顾一下,本文主要是介绍了博主从为什么要制作这样的一个工具出发,到一步步的实现,到使用方法以及后续拓展等。

回到起点,虽然国内的版权意识相比较而言还是比较淡薄。但已经是进步很大了,而且这也只是个时间问题。

相信,CSDN会把这项工作做得越来越好的。

目录
相关文章
|
3月前
|
机器学习/深度学习 人工智能 数据安全/隐私保护
免费交互式大模型在线图像去除水印.擦除.替换和增强照片项目代码(免费在线图像修复工具)
免费交互式大模型在线图像去除水印.擦除.替换和增强照片项目代码(免费在线图像修复工具)
57 0
|
6月前
|
Web App开发 编解码 iOS开发
如何使用ffmpeg制作透明背景的视频
数字人的视频我是使用的腾讯智影生成带绿幕的视频,要实现透明背景,有个很关键的信息需要知道,不是所有的视频格式(视频编码)都支持透明背景,首先我们最常用的mp4就是不支持(不管是h264还是h265)都不支持,目前支持透明背景的只有少部分视频编码,比如google的vp9(webm)格式,上图中我用就是webm+vp9编码的视频。实测这种视频兼容性也不行,比如在苹果的safari浏览器下,就无法透明背景。
240 0
|
5月前
|
人工智能 搜索推荐 定位技术
证件照尺寸修改、图片背景换色、照片大小压缩…几个在线图片编辑、处理网站推荐
证件照尺寸修改、图片背景换色、照片大小压缩…几个在线图片编辑、处理网站推荐
|
5月前
水晶头制作
水晶头制作。
124 44
|
7月前
|
数据安全/隐私保护 Windows
实用分享-免费录屏工具(无水印)
实用分享-免费录屏工具(无水印)
|
8月前
|
小程序
背景音频制作
背景音频制作
36 0
|
9月前
|
数据安全/隐私保护
五、用PhotoShop去图片的水印 | 微课系列教程
图片,是我们PPT、微课必不可少的素材。在之前的课程中,给大家讲过如何找大图、高清图等,但从网站上找到的一些图片,总是多多少少有一些水印之类的杂物,严重影响我们的使用,今天这一课,就跟着我来一起用Ps去掉图片中你不想要的部分吧!
83 0
|
数据可视化 前端开发 HTML5
Tiff – 值得你体验一下的可视化的字体对比工具
  Tiff 是一款字体对比工具,可视化对比两种字体之间的差异。这是一个工具来帮助比较两种字体,同时学习排版。在这一点上,谷歌 Web 字体作为 Tiff 外部字体文件的唯一来源。由于应用程序使用的一些功能需要 HTML5 和 CSS3 支持,因此请使用现浏览器来使用。
1498 1
|
人工智能 Python
不到100行代码制作各种证件照
不到100行代码制作各种证件照
267 0
不到100行代码制作各种证件照