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

现在很多场合需要将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 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 用来打包文件

python 复制代码
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 主界面代码

python 复制代码
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

相关推荐
nuclear20111 小时前
使用Python 在Excel中创建和取消数据分组 - 详解
python·excel数据分组·创建excel分组·excel分类汇总·excel嵌套分组·excel大纲级别·取消excel分组
Lucky小小吴1 小时前
有关django、python版本、sqlite3版本冲突问题
python·django·sqlite
GIS 数据栈2 小时前
每日一书 《基于ArcGIS的Python编程秘笈》
开发语言·python·arcgis
爱分享的码瑞哥2 小时前
Python爬虫中的IP封禁问题及其解决方案
爬虫·python·tcp/ip
傻啦嘿哟3 小时前
如何使用 Python 开发一个简单的文本数据转换为 Excel 工具
开发语言·python·excel
B站计算机毕业设计超人3 小时前
计算机毕业设计SparkStreaming+Kafka旅游推荐系统 旅游景点客流量预测 旅游可视化 旅游大数据 Hive数据仓库 机器学习 深度学习
大数据·数据仓库·hadoop·python·kafka·课程设计·数据可视化
IT古董3 小时前
【人工智能】Python在机器学习与人工智能中的应用
开发语言·人工智能·python·机器学习
湫ccc4 小时前
《Python基础》之pip换国内镜像源
开发语言·python·pip
hakesashou4 小时前
Python中常用的函数介绍
java·网络·python
菜鸟的人工智能之路4 小时前
极坐标气泡图:医学数据分析的可视化新视角
python·数据分析·健康医疗