Python实现给图片加水印功能

前言

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

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

先看效果

把公众号的封面作为素材

原图是这样的

Python实现给图片加水印功能

加个水印的效果

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/

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

效果如下

Python实现给图片加水印功能

搞定~

命令行使用

本项目参考的那个项目

完整代码

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

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

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

发表评论

相关文章