关于本站
1、基于Django+Bootstrap开发
2、主要发表本人的技术原创博客
3、本站于 2015-12-01 开始建站
这几天使用django-ueditor的时候,总想着能否实现上传的图片自动加水印。
为了能够更加保护我的知识产权,有必要给图片自动加水印。
Python2.7,3x对图片操作需要安装PIL。可用pip命令行安装:
pip install pillow
若你安装不了,就升级pip
python -m pip install --upgrade pip
安装完成之后,测试看看下面模块是否能够正常加载
from PIL import Image
可以正常加载,就写个测试文件,代码如下:
#coding:utf-8 from PIL import Image, ImageDraw, ImageFont #打开当前文件夹的1.png文件 im = Image.open("1.png").convert('RGBA') #创建文本图层 txt = Image.new('RGBA', im.size, (0,0,0,0)) draw = ImageDraw.Draw(txt) mark = u'杨仕航的博客\nhttp://yshblog.com' point = (txt.size[0]-155, txt.size[1]-45) #写入位置 draw.text(point, mark, fill=(255,255,255,255)) #低版本PIL没有这个alpha_composite #out = Image.alpha_composite(im, txt) out = Image.composite(txt, im, txt) out.save('3.png') #保存文件 out.close()
一开始写入的水印只是网址,可以正常写入。但把水印加入中文之后,就出错。
不管怎么修改字符串的编码都不行。后来发现应该加载中文字体才行。
从系统复制一份字体,放到测试脚本的目录中。我复制了微软雅黑字体。名字为msyhbd.ttf,代码修改如下:
#coding:utf-8 from PIL import Image, ImageDraw, ImageFont im = Image.open("1.png").convert('RGBA') txt=Image.new('RGBA', im.size, (0,0,0,0)) draw = ImageDraw.Draw(txt) mark = u'杨仕航的博客\nhttp://yshblog.com' fnt = ImageFont.truetype('msyhbd.ttf', 15) #要加中文字体才能识别中文 point = (txt.size[0]-155, txt.size[1]-45) #位置 draw.text(point, mark, font=fnt, fill=(255,255,255,255)) out=Image.alpha_composite(im, txt) out.save('3.png') out.close()
测试代码可以正常运行之后,就考虑集成到我的网站中。
我使用上传图片的地方是django-ueditor富文本框。该组件可以在我的Github中下载:https://github.com/HaddyYang/django-ueditor (Github我已经更新加水印功能了,但默认没有开启)
当然,你可以借鉴一下,运用到你的网站中。
打开django-ueditor中的ueconfig.json文件,该文件是服务器配置文件。
该文件是json数据,在其末端添加如下设置项:
"openWaterMark": true, "waterMarkText": "杨仕航的博客\nhttp://yshblog.com", "waterMarkFont": "msyhbd.ttf", "waterMarkSize": 15, "waterMarkBottom": 45, "waterMarkRight": 155
各个参数意义如下:
"openWaterMark": 是否开启加水印功能 "waterMarkText": 水印内容 "waterMarkFont": 字体名称 "waterMarkSize": 字体大小 "waterMarkBottom": 下边距 "waterMarkRight": 右边距
然后,打开controller.py文件,添加如下方法:
#加水印 def add_watermark(savePath): try: #判断是否是图片文件 if not os.path.splitext(savePath)[-1].lower() in ['.jpg', '.jpge', '.png', '.bmp']: return #获取配置 config = getConfigContent() is_mark = config.get('openWaterMark', False) #是否开启加水印功能 watermark = config.get('waterMarkText', '') #水印内容 font = config.get('waterMarkFont', 'msyhbd.ttf') #字体 size = config.get('waterMarkSize', 15) #字体大小 bottom = config.get('waterMarkBottom', 45) #下边距 right = config.get('waterMarkRight', 155) #右边距 #判断是否开启了加水印功能 if not is_mark: return #python2.7 pillow from PIL import Image, ImageDraw, ImageFont #打开图片 im = Image.open(savePath).convert('RGBA') #透明的图层,用于写文本 text_layer = Image.new('RGBA', im.size, (0,0,0,0)) draw = ImageDraw.Draw(text_layer) #加载字体,设置大小 font_path = os.path.join(os.path.dirname(__file__), font) fnt = ImageFont.truetype(font_path, 15) #要加中文字体才能识别中文 point = (text_layer.size[0]-right, text_layer.size[1]-bottom) #位置 draw.text(point, watermark, font=fnt, fill=(255,255,255,255)) #低版本PIL没有这个alpha_composite #out=Image.alpha_composite(im, text_layer) out = Image.composite(text_layer, im, text_layer) out.save(savePath) out.close() except Exception as e: print('[error]', e.message)
添加完成之后,同样在这个文件中,找到上传文件方法uploadFile,在里面加入加水印的函数。如下图位置:
保存代码,重启服务。上传图片测试效果。
测试发现回车符的问题,我在本地测试是可以识别\n为回车符,而上传的服务器却不识别。
建议尽量不用多行文本,用一行文本,而且内容尽可能短。