背景

最近有一些图片需要增加水印,找了一圈也没看见比较好的工具,又不想用破解的PS,干脆自己做了一个GUI工具,有需要的同学自取

功能

  • 支持水印预览
  • 自定义水印文字内容
  • 支持行楷和微软雅黑两种字体
  • 支持自定义字号
  • 支持自定义水印颜色
  • 支持自定义水印间距
  • 支持自定义水印透明度
  • 支持自定义水印旋转角度
  • 支持批量给图片增加水印
  • 仅支持Windows平台(用到了windows上的字体)

预览

使用方式

方法一:运行Python脚本。

电脑上需要安装python3运行环境

# 安装依赖包
pip install pillow pysimplegui
# 将下面的源码保存为: image_watermark_tool.py
python image_watermark_tool.py

方法二:直接下载exe文件,双击运行即可。

链接: https://pan.baidu.com/s/1veoNlDJOecq7bw0rQB-FYg

提取码: b9pe

exe程序由下面的源码打包而成

pyinstaller -F -w image_watermark_tool.py

源码

# author zhenglisai
from PIL import Image, ImageDraw, ImageFont
import PySimpleGUI as sg
import os
from io import BytesIO
import base64
import traceback def add_watermark(image, msg, font, font_size, color, distance, transparency, angle):
if font == "xingkai":
font_name = "C:\\WINDOWS\\Fonts\\STXINGKA.TTF"
else:
font_name = "C:\\WINDOWS\\Fonts\\msyh.ttc"
font = ImageFont.truetype(font_name, int(font_size))
if color == "" or color == "None":
r = 0
g = 0
b = 0
else:
color = color.replace("#", "0x")
color = int(color, base=16) if isinstance(color, str) else color
r = (color >> 16) & 0xff
g = (color >> 8) & 0xff
b = color & 0xff
background = Image.new('RGBA', (image.size[0] * 3, image.size[1] * 3), (0, 0, 0, 0))
background.paste(image, image.size)
font_len = len(msg)
rgba_image = background.convert('RGBA')
text_overlay = Image.new('RGBA', rgba_image.size, (255, 255, 255, 0))
image_draw = ImageDraw.Draw(text_overlay)
for i in range(0, rgba_image.size[0], font_len * 40 + int(distance)):
for j in range(0, rgba_image.size[1], int(distance)):
image_draw.text((i, j), msg, font=font, fill=(r, g, b, int(transparency)))
text_overlay = text_overlay.rotate(int(angle))
image_result = Image.alpha_composite(rgba_image, text_overlay)
image_result = image_result.crop((image.size[0], image.size[1], image.size[0] * 2, image.size[1] * 2))
return image_result frame = [
[sg.Text("水印"), sg.InputText("郑立赛", key="text", enable_events=True)],
[sg.Text("字体"), sg.Radio("行楷", "font", default=True, key="xingkai", enable_events=True), sg.Radio("微软雅黑", "font", key="yahei", enable_events=True)],
[sg.Text("字号"), sg.Slider(range=(1, 100), default_value=36, key="font_size", orientation='horizontal', enable_events=True)],
[sg.Button("选择水印颜色", button_type=sg.BUTTON_TYPE_COLOR_CHOOSER, target="color"),sg.InputText("#000000", enable_events=True, key="color", readonly=True, size=(10, 10))],
[sg.Text("间距"), sg.Slider(range=(1, 500), default_value=200, key="distance", orientation='horizontal', enable_events=True)],
[sg.Text("透明度"), sg.Slider(range=(0, 255), default_value=50, key="transparency", orientation='horizontal', enable_events=True)],
[sg.Text("角度"), sg.Slider(range=(-90, 90), default_value=45, key="angle", orientation='horizontal', enable_events=True)],
[sg.Text("使用说明", text_color="red")],
[sg.Text("第一步:调整参数,预览水印")],
[sg.Text("第二部:点击下方选择图片")],
[sg.Button("打开图片", key="open_image")],
[sg.Text("处理进度"), sg.ProgressBar(100, size=(30, 10), orientation="h", key="progress")]
]
frame_image = [
[sg.Image(key="image"), sg.Sizer(640, 480)]
] layout = [
[sg.Frame(title="参数", layout=frame), sg.Frame(title="效果预览", layout=frame_image, element_justification="center")]
]
default_windows_size = (800, 480)
window = sg.Window("批量添加水印工具",
layout,
default_element_size=(40, 1),
grab_anywhere=True,
size=default_windows_size,
resizable=True,
finalize=True,
enable_close_attempted_event=True
) while True:
try:
event, value = window.read()
if event == sg.WIN_CLOSED:
break
if event == "open_image":
image_path_list = sg.popup_get_file("选择图片",
no_window=True,
multiple_files=True
)
source_image_path = os.path.sep.join(image_path_list[0].split("/")[:-1])
result_path = os.path.join(source_image_path, "watermark")
if not os.path.exists(result_path):
os.mkdir(result_path)
image_count = len(image_path_list)
text = value["text"]
font_size = value["font_size"]
distance = value["distance"]
transparency = value["transparency"]
angle = value["angle"]
color = value["color"]
progress_bar = window["progress"]
count = 1
total = len(image_path_list)
for image_path in image_path_list:
image_name = image_path.split("/")[-1].split(".")[0]
image_source = Image.open(image_path)
if value["yahei"]:
font = "yahei"
else:
font = "xingkai"
image_result = add_watermark(image_source, text, font, font_size, color, distance, transparency, angle)
image_result_path = os.path.join(result_path, "%s.png" % image_name)
image_result.save(image_result_path)
buffered = BytesIO()
image_result.save(buffered, format="PNG")
data = base64.b64encode(buffered.getvalue())
window["image"].update(data=data)
progress_bar.UpdateBar(current_count=count, max=total)
count += 1
sg.popup_ok('%s张水印图片已保存在: %s' % (image_count, result_path))
if event in ["angle", "transparency", "distance", "yahei", "xingkai", "font_size", "text", "color"]:
image_demo = Image.new('RGBA', (640, 480), (0, 0, 0, 0))
if value["yahei"]:
font = "yahei"
else:
font = "xingkai"
image_result = add_watermark(image_demo, value["text"], font, value["font_size"], value["color"], value["distance"], value["transparency"], value["angle"])
buffered = BytesIO()
image_result.save(buffered, format="PNG")
data = base64.b64encode(buffered.getvalue())
window["image"].update(data=data)
except:
sg.Print(traceback.format_exc())
window.close()

【Python】批量给图片增加水印工具的更多相关文章

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

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

  2. C#图片增加水印

    给图片增加水印 1.引用 using System.Drawing; 2.代码实现 string ImagePath = @"C:\Users\RAPOO\Pictures\Camera R ...

  3. Python批量修改图片格式和尺寸

    Python批量修改图片格式和尺寸 备注: 1.导入了PIL库,是处理图片用的,很强大; 2.导入了的win32库,是判断隐藏文件用的,我们的项目需要删除隐藏文件,不需要的可以直接找到删除. 3.导入 ...

  4. Python实现给图片加水印功能

    前言 最近忙得连轴转,很久没更新博客了,代码倒是没啥写,积累了好些东西,接下来一有时间就来更新吧~ 本文记录使用Python实现给图片添加水印的功能实现过程 先看效果 把公众号的封面作为素材 原图是这 ...

  5. Python 批量修改图片格式和尺寸

    公司的一个项目要求把所有4096x4096的图片全部转化成2048x2048的图片,这种批量转换图片大小的软件网上很多,我的同事原来使用的美图看看的批量转换,但是稍微有点麻烦,每次还需要指定要转换的图 ...

  6. tinypng的python批量压缩图片功能

    tinypng网站提供的图片压缩功能很不错,但是直接在网站上压缩有限制,大量压缩图片时比较麻烦,还好官方提供了很多脚本的自动化压缩接口.下面简单说下python批量压缩步骤. 1.申请api key ...

  7. python批量裁剪图片

    """用Pythonp批量裁剪图片""" from PIL import Imageimport matplotlib.pyplot as ...

  8. 【python】PIL 批量绘制图片矩形框工具

    工具采用PIL:Python Imaging Library,图像处理标准库.PIL功能非常强大,但API却非常简单易用. 安装PIL 在Debian/Ubuntu Linux下直接通过apt安装 $ ...

  9. ps技术--批量给图片加水印

    在日常的办公过程中,对于一些比较重要的文件的扫描件需要特殊处理,这时我们就需要给它们加上水印,保证它们的用途唯一,而这些扫描件很多,不可能一一给他们加水印,所以为提高工作效率,我们就可以使用一些小软件 ...

随机推荐

  1. c++中的数学函数

    math.h 数学函数库,一些数学计算的公式的具体实现是放在math.h里,具体有:1 三角函数double sin (double);double cos (double);double tan ( ...

  2. Mybatis一级缓存的锅

    问题背景 项目开发中有一个树形数据结构,不像经典组织结构树.菜单级别树,我们这个树形结构是用户后期手动建立起来的关系.因此数据库表结构为两张表:数据记录表.记录关系表,通过业务规则限制,形成的树形结构 ...

  3. 测试小姐姐问我 gRPC 怎么用,我直接把这篇文章甩给了她

    原文链接: 测试小姐姐问我 gRPC 怎么用,我直接把这篇文章甩给了她 上篇文章 gRPC,爆赞 直接爆了,内容主要包括:简单的 gRPC 服务,流处理模式,验证器,Token 认证和证书认证. 在多 ...

  4. mybatis学习笔记(1)基本环境

    1.pom引入 <dependencies> <dependency> <groupId>org.mybatis</groupId> <artif ...

  5. OO第三单元——JML规格化设计

    OO第三单元--JML规格化设计 JML语言的理论基础以及应用工具链情况 理论基础 JML是对JAVA程序进行规格化设计的一种表示语言,是一种行为接口规格语言.JML整合了Java和JAVAdoc,并 ...

  6. gson中TypeAdapter实现自定义序列化操作

    最近在项目中遇到这么一个问题,我们后台需要向前端返回一个 json 数据,就是将一个地理位置对象以json的格式返回到前台,但是这个地理位置对象中的经纬度是Double数据类型,项目中规定,如果经纬度 ...

  7. Noip模拟70 2021.10.6

    T1 暴雨 放在第一道的神仙题,不同的做法,吊人有的都在用线段树维护$set$预处理 我是直接$dp$的,可能代码的复杂度比那种的稍微小一点 设$f[i][j][p][0/1]$表示考虑了前$i$列, ...

  8. reactnative实现qq聊天消息气泡拖拽消失效果

    前言(可跳过) 我在开发自己的APP时遇到了一个类似于qq聊天消息气泡拖拽消息的需求,因为在网上没有找到相关的组件,所以自己动手实现了一下 需求:对聊天消息气泡拖拽到一定长度松开时该气泡会消失(可自行 ...

  9. hdu 5092 Seam Carving (简单数塔DP,题没读懂,,不过可以分析样例)

    题意: 给一个m*n的矩阵,每格上有一个数. 找从第1行到第m行的一条路径,使得这条路径上的数之和最小. 路径必须满足相邻两行所选的两个数的纵坐标相邻(即一个格子必须是另一个格子的周围八个格子中的一个 ...

  10. 安装与卸载JDK8

    前言:学习Java的第一步需要先配置好JDK环境,而JDK8是目前使用最广泛的JDK版本.本文讲解了如何下载安装和卸载JDK8.以下环境为Windows10 下载JDK安装包 Oracle官网 所有J ...