水印工具制作

简介: 诱因原理图片水印文字水印完整代码使用方法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会把这项工作做得越来越好的。

目录
相关文章
|
域名解析 网络协议 Linux
【Shell 命令集合 网络通讯 】Linux 设置和管理网络接口配置信息 netconfig命令 使用指南
【Shell 命令集合 网络通讯 】Linux 设置和管理网络接口配置信息 netconfig命令 使用指南
950 1
|
JavaScript 前端开发 容器
粘性定位Position:sticky已死?
粘性定位(`sticky`)是CSS3新增的一种定位方式,结合了相对定位(`relative`)和固定定位(`fixed`)的特点。当页面滚动时,元素在跨越特定阈值前表现为相对定位,之后则固定在指定位置。它常用于导航菜单等需要吸附效果的场景。 **特点:** - 需配合`top`、`right`、`bottom`或`left`属性使用。 - 相对于父元素定位,而非整个视窗(与`fixed`区别)。 - 兼容性:低版本浏览器可能不支持。 通过案例可见,`sticky`可简化以往需JS实现的效果,但实际应用需考虑浏览器兼容性问题。
粘性定位Position:sticky已死?
|
9月前
|
存储 监控 安全
API全面方案:多平台API管理,一站式解决!
本文探讨如何构建一站式多平台API管理方案,应对分散管理、文档不一、监控困难、安全风险等挑战,涵盖网关路由、统一注册、自动文档、集中监控、智能测试与安全治理六大核心能力,并提供开源与商业选型建议,助力企业提升效率、稳定性和安全性。(239字)
|
10月前
|
UED
验证码短信突发失败?阿里云「验证码兜底解决方案」保障业务高可用
当用户自定义的短信签名或模板因运营商审核等原因导致发送失败时,系统会自动切换至兜底签名和兜底模板,作为一种备用发送策略,确保验证码仍能成功发送。
816 0
|
存储 弹性计算 固态存储
阿里云服务器收费标准与最新活动价格一览,轻量应用服务器38元起,云服务器99元起
阿里云服务器最新价格参考,云服务器的收费标准主要包含CPU内存配置价格、云盘价格和带宽价格等,官方会不定期调整收费标准和活动价格,目前,共享型经济型e实例云服务器2核2G3M还是只要99元1年,独享型通用算力型u1实例云服务器2核4G5M企业用户购买只要199元1年,而轻量应用服务器的抢购价格已经到了38元1年,每天仅需0.1元。更多配置的云服务器的最新收费标准和活动价格表见下文。
|
Java
【源码】【Java并发】【ConcurrentHashMap】适合中学体质的ConcurrentHashMap
本文深入解析了ConcurrentHashMap的实现原理,涵盖JDK 7与JDK 8的区别、静态代码块、构造方法、put/get/remove核心方法等。JDK 8通过Node数组+链表/红黑树结构优化并发性能,采用CAS和synchronized实现高效锁机制。文章还详细讲解了hash计算、表初始化、扩容协助及计数更新等关键环节,帮助读者全面掌握ConcurrentHashMap的工作机制。
453 6
【源码】【Java并发】【ConcurrentHashMap】适合中学体质的ConcurrentHashMap
|
Linux 虚拟化 Windows
VMware隐藏黑科技!CentOS安装这个神器效率翻倍 文件互传竟比U盘还快?
### 安装VMtools的作用及步骤 安装VMtools可以实现Windows与CentOS之间的字符串和命令粘贴、文件夹共享等操作。在CentOS中,通过VMware菜单栏选择“VMware Tools”,将下载的压缩包拷贝到`/opt`目录并解压。接着进入终端,使用`./vmware-install.pl`命令完成安装。安装后重启系统,即可实现Windows与CentOS之间的字符和文件共享。具体步骤包括解压文件、启动命令行终端、安装VMtools以及配置文件共享。
VMware隐藏黑科技!CentOS安装这个神器效率翻倍 文件互传竟比U盘还快?
|
人工智能 自然语言处理 测试技术
通义灵码入选 “2025 年值得关注的 AIGC 产品”,是唯一入选的 AI 编程产品
阿里云的通义灵码是一款基于通义大模型的AI编程助手,能够智能生成代码、优化结构、排查错误并自动生成测试用例,支持多种主流编程语言。在2025年入选《值得关注的AIGC产品》榜单,凭借卓越技术与广泛应用场景成为国内开发者首选。通义灵码已在国内多个行业落地,大幅提升开发效率与代码质量,同时针对中文编程场景优化,支持企业内网部署保障数据安全,推动AI编程技术在教育与科研领域的创新应用。

热门文章

最新文章