利用pythonstudio写的PDF、图片批量水印生成器,可同时为不同读者生成多组水印

devtools/2024/11/6 22:57:58/

现在很多场合需要将PDF或图片加水印,本程序利用pythonstudio编写。

第一步 界面

在这里插入图片描述
其中:

LstMask:列表框

  • PopupMenu:PmnMark

LstFiles:列表框

  • PopupMenu:PmnFiles

OdFiles:文件选择器

  • Filter:PDF文件(.PDF)|.PDF|图像文件(.JPG)|.JPG|图像文件(.png)|.png
  • Option-OfAllowMultiSelection:True

其余一眼都能看出来

代码:

模块1:m_water 用来打水印

python">
import os
import iofrom PyPDF2 import PdfWriter, PdfReader
from reportlab.lib import pagesizes  # 页面样式
from reportlab.lib.units import cm
from reportlab.pdfbase import pdfmetrics  # 注册字体
from reportlab.pdfbase.ttfonts import TTFont  # 字体类
from reportlab.pdfgen import canvasfrom watermarker.marker import add_mark
from PIL import Imagepdfmetrics.registerFont(TTFont('SimHei', os.path.join(os.path.dirname(os.path.abspath(__file__)), "bird.ttf")))# 生成水印文件
def create_water_mark(text):packet = io.BytesIO()# 创建一个带有水印的新PDF页my_canvas = canvas.Canvas(packet, pagesizes.A0)# 设置水印字体my_canvas.setFont("SimHei", 40)# 填充色my_canvas.setFillColorRGB(0, 0, 0)# 透明度my_canvas.setFillAlpha(0.1)# 设置字体旋转度数my_canvas.rotate(15)# x轴的3cm处,到24结束,步长是10for i in range(3, 24, 10):# y轴的for j in range(-5, 30, 5):my_canvas.drawString(i * cm, j * cm, text)my_canvas.save()packet.seek(0)return PdfReader(packet)def add_watermark(input_pdf_path, output_pdf_path, watermark_text):# 创建水印watermark = create_water_mark(watermark_text)# 读取输入 PDFpdf_reader = PdfReader(input_pdf_path)pdf_writer = PdfWriter()# 遍历每一页,将水印添加到每一页for page in pdf_reader.pages:page.merge_page(watermark.pages[0])  # 将水印添加到当前页面pdf_writer.add_page(page)# 写入到输出 PDF 文件with open(output_pdf_path, "wb") as output_pdf:pdf_writer.write(output_pdf)def add_pic_watermark(input_jpg_path,out_jpg_path, watermark_text):# 加水印add_mark(file=input_jpg_path,out=out_jpg_path,mark=watermark_text,opacity=0.3,angle=30,space=80)
##    add_mark(file=f"{cwd}\page_{i + 1}.jpg" , out=cwd, mark=EPdf.stamp,opacity=EPdf.tran,angle=30,space=80)def main():passif __name__ == '__main__':main()

模块2:m_zip 用来打包文件

python">import zipfile
import osdef compress_folder(folder_path, output_path):with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zipf:for root, dirs, files in os.walk(folder_path):for file in files:file_path = os.path.join(root, file)arc_name = os.path.relpath(file_path, folder_path)zipf.write(file_path, arc_name)def main():passcompress_folder("111","111.zip")if __name__ == '__main__':main()

Unit1.py 主界面代码

python">import os
from glcl import *
from m_water import *
from m_zip import *
import shutilclass Form1(Form):def __init__(self, owner):self.PgbFiles = ProgressBar(self)self.LblStat = Label(self)self.PmnFiles = PopupMenu(self)self.PmnMark = PopupMenu(self)self.OdFiles = OpenDialog(self)self.BtnAddFiles = Button(self)self.Label3 = Label(self)self.Label2 = Label(self)self.BtnClose = Button(self)self.BtnMark = Button(self)self.Label1 = Label(self)self.EdtMark = Edit(self)self.LstFiles = ListBox(self)self.LstMark = ListBox(self)self.BtnBeginMark = Button(self)self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "Unit1.pydfm"))self.BtnClose.OnClick = self.BtnCloseClickself.BtnBeginMark.OnClick = self.BtnBeginMarkClickself.LstFiles.OnClick = self.LstFilesClickself.MniFiles.OnClick = self.MniFilesClickself.PmnFiles.OnPopup = self.PmnFilesPopupself.BtnAddFiles.OnClick = self.BtnAddFilesClickself.MniDel.OnClick = self.MniDelClickself.PmnMark.OnPopup = self.PmnMarkPopupself.BtnMark.OnClick = self.BtnMarkClick# 把水印名加入到列表def BtnMarkClick(self, Sender):# 如果 EDT不为空,则加至列表if self.EdtMark.Text.strip()!="":# 没有重复if self.LstMark.Items.IndexOf(self.EdtMark.Text.strip())>-1:ShowMessage("当前水印已存在,请检查后重新输入。")returnself.LstMark.Items.Add(self.EdtMark.Text.strip())# 清除EDTself.EdtMark.Text=""else:ShowMessage("请先填写需要添加的水印内容。")# 如果水印名有值,就显示删除def PmnMarkPopup(self, Sender):self.MniDel.Enabled=True if self.LstMark.ItemIndex>-1 else False# 如果文件有值,就显示删除def PmnFilesPopup(self, Sender):self.MniDel.Enabled=True if self.LstFiles.ItemIndex>-1 else False# 确认是否要删除水印,然后删除def MniDelClick(self, Sender):if Application.MessageBox("是否要删除"+ self.LstMark.Items[self.LstMark.ItemIndex]+"?","请确认", MB_YESNO)==IDYES:self.LstMark.DeleteSelected()# 确认是否要删除文件,然后删除def MniFilesClick(self, Sender):if Application.MessageBox("是否要删除"+ self.LstFiles.Items[self.LstFiles.ItemIndex]+"?","请确认", MB_YESNO)==IDYES:self.LstFiles.DeleteSelected()# 选择文件并添加到列表中def BtnAddFilesClick(self, Sender):if self.OdFiles.Execute():for item in self.OdFiles.Files:# 如果不重复就添加if self.LstFiles.Items.IndexOf(item)==-1:self.LstFiles.Items.Add(item)# 显示选中项的提示def LstFilesClick(self, Sender):self.LstFiles.Hint=self.LstFiles.Items[self.LstFiles.ItemIndex]# 循环打水印def BtnBeginMarkClick(self, Sender):# 如果没有文件或水印,退出if self.LstFiles.Count==0 or self.LstMark.Count==0:ShowMessage("请确认添加好水印和文件后再进行操作。")return# 将所有按钮都禁用self.BtnAddFiles.Enabled=Falseself.BtnBeginMark.Enabled=Falseself.BtnMark.Enabled=Falseself.BtnClose.Enabled=False# 提示需要较长时间ShowMessage("共有"+str(self.LstFiles.Count * self.LstMark.Count)+"个文件要打水印并打包,所需时间较长,请确认后开始操作。")# 进度条最大值self.PgbFiles.max=self.LstFiles.Count * self.LstMark.Countself.PgbFiles.Position=0self.LblStat.Caption="正在建立文件夹"# 建立以水印名为名字的文件夹try:for folder in self.LstMark.Items:if os.path.exists(folder)==False:os.mkdir(folder)except:ShowMessage("建立文件夹失败")returnself.LblStat.Caption="开始打水印"# 循环水印for mark in self.LstMark.Items:# 循环文件for markfile in self.LstFiles.Items:# 如果是pdf,打PDF水印,存在水印文件夹if markfile[-4:].upper()==".PDF":try:outfilename=os.path.join( mark, markfile[markfile.rfind("\\")+1:])add_watermark(markfile,outfilename,mark)except:ShowMessage(markfile[markfile.rfind("\\")+1:]+"文件建立失败")else:# 如果是图片,打图片水印,存在水印文件夹下try:add_pic_watermark(markfile,mark,mark)except:ShowMessage(markfile[markfile.rfind("\\")+1:]+"文件建立失败")self.PgbFiles.Position+=1# 打包进度self.PgbFiles.Max=self.LstMark.Countself.PgbFiles.Position=0# 所有水印打完后,每个水印文件夹打包if os.path.exists("output")==False:os.mkdir("output")self.LblStat.Caption="开始文件打包"for folder in self.LstMark.Items:compress_folder(folder,"output\\"+folder+".zip")self.PgbFiles.Position+=1# 删除临时文件for folder in self.LstMark.Items:shutil.rmtree(folder)# 恢复所有按钮self.BtnAddFiles.Enabled=Trueself.BtnBeginMark.Enabled=Trueself.BtnMark.Enabled=Trueself.BtnClose.Enabled=Trueself.LblStat.Caption="打水印完成"ShowMessage("打水印、打包完成,请在当前文件夹下检查ZIP文件。")self.LblStat.Caption=""self.LstMark.Clear()self.LstFiles.Clear()def BtnCloseClick(self, Sender):self.Close()

伸手党可直接下载可执行文件
https://download.csdn.net/download/gxchai/89956703


http://www.ppmy.cn/devtools/131856.html

相关文章

uniapp使用echart

一 直线图 三中国地图 <template><view class"content"><l-echart ref"chartRef"></l-echart></view> </template><script setup> import { ref, onMounted } from "vue"; import geoJson from &quo…

利用游戏引擎的优势

大家好&#xff0c;我是小蜗牛。 在当今快速发展的游戏产业中&#xff0c;选择合适的游戏引擎对开发者来说至关重要。Cocos Creator作为一款功能强大且灵活的游戏引擎&#xff0c;为开发者提供了丰富的工具和资源&#xff0c;使他们能够高效地开发出优秀的游戏。本文将探讨如何…

24.11.6 PySimpleGUI库和pymsql 库以及人脸识别小项目

PySimpleGUI 库 PySimpleGUI 是一个用于简化 GUI 编程的 Python 包&#xff0c;它封装了多种底层 GUI 框架&#xff08;如 tkinter、Qt、WxPython 等&#xff09;&#xff0c;提供了简单易用的 API。PySimpleGUI 包含了大量的控件&#xff08;也称为小部件或组件&#xff09;&…

国家级汽车检测中心联合开源网安打造安全解决方案,提升行业安全检测水平

某汽车检测中心是我国交通运输行业智能商用车领域的国家级检测中心&#xff0c;以商用车智能化、网联化检测能力引领&#xff0c;拥有交通运输部及工业和信息化部认定的“智能网联汽车自动驾驶封闭测试场地测试基地”和“交通运输部自动驾驶交通技术研发中心”&#xff0c;主要…

GPT-SoVITS 部署方案

简介 当前主流的开源TTS框架&#xff0c;这里介绍部署该服务的主要流程和我在使用过程中出现的问题。 使用的技术 Docker、Jupyter、Python、C# 部署 docker的使用 拉取命令 docker pull jupyter/base-notebook:python-3.10.11jupyter的访问 docker运行以后可以直接使用…

【C++】RBTree——红黑树

文章目录 一、红黑树的概念1.1 红⿊树的规则&#xff1a;1.2 理解最长路径长度不超过最短路径长度的 2 倍1.3 红⿊树的效率 二、 红⿊树的实现2.1 红⿊树的结构2.2 红⿊树的插⼊2.2.1 红⿊树树插⼊⼀个值的⼤概过程 2.3 红⿊树的插⼊代码实现 一、红黑树的概念 红⿊树是⼀棵⼆…

Claude发布桌面客户端!新功能支持分析100页PDF的图像!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;专注于分享AI全维度知识&#xff0c;包括但不限于AI科普&#xff0c;AI工…

「Mac畅玩鸿蒙与硬件22」鸿蒙UI组件篇12 - Canvas 组件的动态进阶应用

在鸿蒙应用中&#xff0c;Canvas 组件可以实现丰富的动态效果&#xff0c;适合用于动画和实时更新的场景。本篇将介绍如何在 Canvas 中实现动画循环、动态进度条、旋转和缩放动画&#xff0c;以及性能优化策略。 关键词 Canvas 组件动态绘制动画效果动态进度条旋转和缩放性能优…