现在很多场合需要将PDF或图片加水印,本程序利用pythonstudio编写。
第一步 界面
其中:
LstMask:列表框
- PopupMenu:PmnMark
LstFiles:列表框
- PopupMenu:PmnFiles
OdFiles:文件选择器
- Filter:PDF文件(.PDF)|.PDF|图像文件(.JPG)|.JPG|图像文件(.png)|.png
- Option-OfAllowMultiSelection:True
其余一眼都能看出来
代码:
模块1:m_water 用来打水印
import os
import io
from 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 canvas
from watermarker.marker import add_mark
from PIL import Image
pdfmetrics.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结束,步长是10
for 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)
# 读取输入 PDF
pdf_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():
pass
if __name__ == '__main__':
main()
模块2:m_zip 用来打包文件
import zipfile
import os
def 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():
pass
compress_folder("111","111.zip")
if __name__ == '__main__':
main()
Unit1.py 主界面代码
import os
from glcl import *
from m_water import *
from m_zip import *
import shutil
class 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.BtnCloseClick
self.BtnBeginMark.OnClick = self.BtnBeginMarkClick
self.LstFiles.OnClick = self.LstFilesClick
self.MniFiles.OnClick = self.MniFilesClick
self.PmnFiles.OnPopup = self.PmnFilesPopup
self.BtnAddFiles.OnClick = self.BtnAddFilesClick
self.MniDel.OnClick = self.MniDelClick
self.PmnMark.OnPopup = self.PmnMarkPopup
self.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("当前水印已存在,请检查后重新输入。")
return
self.LstMark.Items.Add(self.EdtMark.Text.strip())
# 清除EDT
self.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=False
self.BtnBeginMark.Enabled=False
self.BtnMark.Enabled=False
self.BtnClose.Enabled=False
# 提示需要较长时间
ShowMessage("共有"+str(self.LstFiles.Count * self.LstMark.Count)+"个文件要打水印并打包,所需时间较长,请确认后开始操作。")
# 进度条最大值
self.PgbFiles.max=self.LstFiles.Count * self.LstMark.Count
self.PgbFiles.Position=0
self.LblStat.Caption="正在建立文件夹"
# 建立以水印名为名字的文件夹
try:
for folder in self.LstMark.Items:
if os.path.exists(folder)==False:
os.mkdir(folder)
except:
ShowMessage("建立文件夹失败")
return
self.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.Count
self.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=True
self.BtnBeginMark.Enabled=True
self.BtnMark.Enabled=True
self.BtnClose.Enabled=True
self.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