前言

最近忙得连轴转,很久没更新博客了,代码倒是没啥写,积累了好些东西,接下来一有时间就来更新吧~

本文记录使用Python实现给图片添加水印的功能实现过程

先看效果

把公众号的封面作为素材

原图是这样的

加个水印的效果

实现代码

主要实现是参考GitHub上一个项目的:https://github.com/2Dou/watermarker

用到了Pillow库,使用前请先安装,一般要在Django中保存图片也需要安装这个库的。所以这个依赖可以说是比较友好的。

这个项目是命令行工具,而我是在Django项目中用,所以我做了魔改

核心代码如下(这段代码是在我封装的一个类里面)

origin_image = Image.open(self.image_path)
origin_image = ImageOps.exif_transpose(origin_image) # 计算字体的宽度、高度
width = len(self.text) * self.size
height = round(self.size * self.font_height_crop) # 创建水印图片
watermark_image = Image.new(mode='RGBA', size=(width, height)) # 生成文字
draw_table = ImageDraw.Draw(im=watermark_image)
draw_table.text(
xy=(0, 0),
text=self.text,
fill=self.color,
font=ImageFont.truetype(self.font_file, size=self.size)
)
del draw_table # 裁剪空白
watermark_image = Watermarker.crop_image_edge(watermark_image) # 设置透明度
Watermarker.set_image_opacity(watermark_image, self.opacity) # 计算斜边长度
c = int(math.sqrt(origin_image.size[0] * origin_image.size[0] + origin_image.size[1] * origin_image.size[1])) # 以斜边长度为宽高创建大图(旋转后大图才足以覆盖原图)用于覆盖在原图之上
watermark_mask = Image.new(mode='RGBA', size=(c, c)) # 在大图上生成水印文字
y, idx = 0, 0
while y < c:
# 制造x坐标错位
x = -int((watermark_image.size[0] + self.space) * 0.5 * idx)
idx = (idx + 1) % 2 while x < c:
# 在该位置粘贴mark水印图片
watermark_mask.paste(watermark_image, (x, y))
x = x + watermark_image.size[0] + self.space
y = y + watermark_image.size[1] + self.space # 将大图旋转一定角度
watermark_mask = watermark_mask.rotate(self.angle) # 在原图上添加大图水印
if origin_image.mode != 'RGBA':
origin_image = origin_image.convert('RGBA')
origin_image.paste(
watermark_mask, # 大图
(int((origin_image.size[0] - c) / 2), int((origin_image.size[1] - c) / 2)), # 坐标
mask=watermark_mask.split()[3]
)
del watermark_mask

我把这个加水印的功能封装成了一个类

class Watermarker(object):
"""图片水印工具"""
django_support = False def __init__(
self, image_path: str, text: str,
angle=30,
color='#8B8B1B',
font_file='青鸟华光简琥珀.ttf',
font_height_crop=1.2,
opacity=0.15,
quality=80,
size=50,
space=75,
):
...
@staticmethod
def set_image_opacity(image: Image, opacity: float):
...
@staticmethod
def crop_image_edge(image: Image):
...
@property
def image(self):
...
def save(self, file_path: str, image_format: str = 'png'):
...
def show(self):
...

使用方法

简单使用

w = Watermarker('codelab.png', '程序设计实验室', size=200)
# 显示加了水印的图片
w.show()
# 保存
w.save('save.png')

在Django中使用

以我封装的 DjangoStarter 框架为例,直接把Image对象写入Http响应里

from io import BytesIO
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponse
from django_starter.contrib.watermark import Watermarker def add_watermark(request, pk):
text = request.GET.get('text', timezone.now().strftime('%Y-%m-%d %H:%M:%S'))
photo = get_object_or_404(Photo, pk=pk)
image = Watermarker(photo.photo.path, text).image # 将图片保存到内存中
with BytesIO() as f:
image.save(f, 'png')
# 返回图片数据流
return HttpResponse(f.getvalue(), content_type='image/png')

路由配置

from django.urls import path
from . import views app_name = 'photo'
urlpatterns = [
path('photo/<int:pk>/add_watermark/', views.add_watermark, name='add_watermark'),
]

这样配置之后,访问链接:http://[host]:[port]/photo/1/add_watermark/

就可以看到加了水印的图片了

效果如下

搞定~

命令行使用

本项目参考的那个项目

完整代码

GitHub gist:https://gist.github.com/Deali-Axy/e22ea79bfbe785f9017b2e3cd7fdb3eb

PS:Github gist是个代码片段工具,最近刚刚用起来,感觉还蛮不错的

有时候用来记录和分享一些代码片段很方便,不需要专门创建一个仓库

Python实现给图片加水印功能的更多相关文章

  1. 火车头dede采集接口,图片加水印,远程图片本地化,远程无后缀的无图片本地化

    <?php /* [LocoySpider] (C)2005-2010 Lewell Inc. 火车采集器 DedeCMS 5.7 UTF8 文章发布接口 Update content: 图片加 ...

  2. PHPThumb处理图片,生成缩略图,图片尺寸调整,图片截取,图片加水印,图片旋转

    [强烈推荐]下载地址(github.com/masterexploder/PHPThumb). 注意这个类库有一个重名的叫phpThumb,只是大小写的差别,所以查找文档的时候千万注意. 在网站建设过 ...

  3. c#封装DBHelper类 c# 图片加水印 (摘)C#生成随机数的三种方法 使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象 c# 制作正方形图片 JavaScript 事件循环及异步原理(完全指北)

    c#封装DBHelper类   public enum EffentNextType { /// <summary> /// 对其他语句无任何影响 /// </summary> ...

  4. TP5缩放图片加水印

    // 给图片增加水印文字 试验缩放图片,放大图片,加水印,加文字功能 public function doCreateImage1($data,$path) { $basePath = ROOT_PA ...

  5. thinkphp 3.2.3整合ueditor 1.4,给上传的图片加水印

    今天分享一下thinkphp 3.2.3整合ueditor 1.4,给上传的图片加水印.博主是新手,在这里卡住了很久(>_<) thinkphp 3.2.3整合ueditor 1.4 下载 ...

  6. php 分享两种给图片加水印的方法

    本文章向码农们介绍 php 给图片加水印的两种方法,感兴趣的码农可以参考一下本文章的源代码. 方法一:PHP最简单的加水印方法 <?php // http://www.manongjc.com ...

  7. Java图片处理(二)图片加水印

    图片加水印,是通过图片重叠绘制实现的.实现代码如下: public static void press(String pressImg, String pressText, String target ...

  8. PHP给图片加水印

    <?php /** *图片加水印 *@param $srcImg 原图 *@param $waterImg 水印图片 *@param $savepath 保存路径 *@param $savena ...

  9. 如何用node.js批量给图片加水印

    上一篇我们讲了如何用node.js给图片加水印,但是只是给某一张图片加,并没有涉及到批量处理.这一篇,我们学习如果批量进行图片加水印处理. 一.准备工作: 首先,你要阅读完这篇文章:http://ww ...

随机推荐

  1. day03_3_流程控制练习题

    # 流程控制练习题 # 一.编程题 1.实现一个课程名称和课程代号的转换器:输入下表中的课程代号,输出课程的名称.用户可以循环进行输入,如果输入0就退出系统.(**使用****switch +whil ...

  2. linux docker .net core 从建立网站到预览

    docker的安装在网上一搜一大把,windows安装的就是exe双击,linux安装需要执行语句 ps:需要准备xftp.xshell.vs 2019.linux服务器.docker账号密码 例如: ...

  3. linux history命令优化

    主要功能: 1, 可以记录哪个ip和时间(精确到秒)以及哪个用户,作了哪些命令 2,最大日志记录增加到4096条 把下面的代码直接粘贴到/etc/profile后面就可以了 #history modi ...

  4. PHP生成器yield使用示例

    <?php function getLines($file) { $f = fopen($file, 'r'); try { while ($line = fgets($f)) { yield ...

  5. Luogu1064 金明的预算方案 (有依赖的背包)

    枚举多个状态 #include <iostream> #include <cstdio> #include <cstring> #include <algor ...

  6. Apache HttpClient 5 使用详细教程

    点赞再看,动力无限. 微信搜「程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. 超文本传输协议(HTTP)可能是当今 ...

  7. tqdm和zip组合使用时无法显示进度条-解决办法

    问题 单独对于可迭代对象iterator使用tqdm时,结合循环就可以在终端显示进度条, 以直观展示程序进度,如下: from tqdm import tqdm textlist = [] for i ...

  8. 强大多云混合多K8S集群管理平台Rancher入门实战

    @ 目录 概述 定义 为何使用 其他产品 安装 简述 规划 基础环境 Docker安装 Rancher安装 创建用户 创建集群 添加Node节点 配置kubectl 创建项目和名称空间 发布应用 偏好 ...

  9. SFSafariViewController 加载的网页与原生oc之间的交互

    问题描述: 工作中碰到这样一种场景, WebApp 已经实现了IM即时通讯及基于WebRTC实现的音视频会议,音视频聊天. 也是半路接手的项目,项目整体是使用WKWebView套壳加载h5 页面实现( ...

  10. 这12款idea插件,能让你代码飞起来

    前言 基本上每个程序员都会写代码,但写代码的速度不尽相同. 为什么有些人,一天只能写几百行代码? 而有些人,一天可以写几千行代码? 有没有办法,可以提升开发效率,在相同的时间内,写出更多的代码呢? 今 ...