main
xingzi 2 years ago
parent d2e79cbe8e
commit a0ce609b94

5
.gitignore vendored

@ -1,4 +1,7 @@
.vscode
.venv
build
dist
*.spec
*.spec

@ -1,129 +0,0 @@
import os
import fitz
from PIL import Image
from tkinter import filedialog
from tkinter import Tk, Button, Label, messagebox, Toplevel
from tkinter.filedialog import askopenfilename
def add_image_watermark(input_image_path, watermark_image_path, output_image_path):
water_width = 100
water_height = 100
water_right = 50
water_bottom = 100
# 打开原始图片和要添加的水印图片
original_img = Image.open(input_image_path).convert("RGBA")
watermark_img = Image.open(watermark_image_path).convert("RGBA")
# 获取原始图片和水印图片的尺寸
original_width, original_height = original_img.size
# 将水印图片缩放到与原始图片相同的大小
watermark_img = watermark_img.resize((water_width, water_height))
# 合并原始图片和水印图片并将结果转换为RGB模式
# watermarked_img = Image.alpha_composite(original_img, watermark_img).convert("RGB")
original_img.paste(watermark_img, (original_width - (water_width+water_right),
original_height-(water_height+water_bottom)), watermark_img)
# 保存水印后的图片为JPEG格式
original_img.save(output_image_path)
class CustomMessageBox(Toplevel):
def __init__(self, master, text, width=400, height=100):
super().__init__(master)
self.transient(master)
self.title("Error")
self.label = Label(self, text=text)
self.label.pack(padx=20, pady=20)
# 设置了宽和高
self.width = width
self.height = height
self.geometry(
f'{width}x{height}+{master.winfo_x()}+{master.winfo_y()}')
self.grab_set() # 使得对话框不会在点击窗口之外的地方时关闭
self.wait_window(self) # 等待对话框关闭
if __name__ == "__main__":
# items = os.listdir(pdfs)
# for f in items:
# name, suffix = os.path.splitext(f)
# if suffix == '.pdf':
# out = outPath + '/' + name + '_watered' + suffix
# input_file = os.path.join(pdfs, f)
# # img2pdf(water_path_png)
# # add_watermark(input_file,water_path_pdf,out)
# add_watermask_fitz(input_file, water_path_pdf, out)
# 获取当前目录
current_dir = os.getcwd()
# 获取脚本自身的路径
script_path = os.path.dirname(os.path.abspath(__file__))
water_path_png = os.path.join(current_dir, 'waters/logo.png')
water_path_pdf = os.path.join(current_dir, 'waters/logo.pdf')
outPath = os.path.join(current_dir, 'output')
pdfs = os.path.join(current_dir, 'pdfs')
def on_closing():
root.destroy()
root.quit()
exit()
def select_file(label, extensions=['pdf', 'png', 'jpeg', 'jpg']):
Tk().withdraw()
file_path = filedialog.askopenfilename()
if file_path:
file_extension = file_path.split('.')[-1].lower()
if file_extension in extensions:
label.config(text=file_path)
else:
CustomMessageBox(root, "无效的文件类型。请选择PDF、PNG、JPEG或JPG文件。")
select_file()
def add_watermask():
file_path = lable_file.cget("text")
water_path = lable_stamp.cget("text")
print(file_path, water_path)
baseaname = os.path.basename(file_path)
name, suffix = os.path.splitext(baseaname)
out_path = os.path.join(os.path.dirname(
file_path), name + '_watered' + suffix)
pdf_file = fitz.open(file_path)
page = pdf_file[0]
page.insert_image(page.bound(), filename=water_path)
pdf_file.save(out_path)
lable_water.config(text=out_path)
root = Tk()
root.protocol("WM_DELETE_WINDOW", on_closing)
root.geometry("600x400")
# 选择文件
lable_file = Label(root, text="请选择PDF或图片")
lable_file.grid(row=0, column=1)
button_file = Button(root, text="选择PDF",
command=lambda: select_file(lable_file))
button_file.grid(row=0, column=0)
# 选择公章
lable_stamp = Label(root, text="请选择选择公章")
lable_stamp.grid(row=1, column=1)
button_stamp = Button(root, text="选择公章", command=lambda: select_file(lable_stamp,
extensions=['png', 'jpeg', 'jpg']))
button_stamp.grid(row=1, column=0)
# 添加水印
button_water = Button(root, text="添加水印", command=add_watermask)
button_water.grid(row=2, column=0)
lable_water = Label(root, text="")
lable_water.grid(row=2, column=1)
root.mainloop()

@ -1,5 +1,6 @@
import os
import sys
import platform
from fpdf import FPDF
from PIL import Image
@ -9,6 +10,11 @@ from tkinter.filedialog import askdirectory, askopenfiles
from pypdf import PdfWriter, PdfReader, Transformation
import math
import random
import subprocess
def get_os():
return platform.system()
def check_output(path):
@ -19,22 +25,22 @@ def check_output(path):
os.mkdir(dir_name)
def img_to_pdf(img_path, out_path='', x=0, y=0, w=100, h=100):
''' 图片转PDF'''
if out_path == '':
def img_to_pdf(img_path, out_path="", x=0, y=0, w=100, h=100):
"""图片转PDF"""
if out_path == "":
dir_name = os.path.dirname(img_path)
basename = os.path.basename(img_path)
name, _ = os.path.splitext(basename)
out_path = os.path.join(dir_name, name+'.pdf')
out_path = os.path.join(dir_name, name + ".pdf")
pdf = FPDF()
pdf.add_page()
pdf.image(img_path, x=x, y=y, w=w, h=h)
pdf.output(out_path, 'F')
pdf.output(out_path, "F")
return out_path
def add_image_watermark(input_path, watermark_path, output_path):
''' 图片添加印章 '''
"""图片添加印章"""
# 打开原始图片和要添加的水印图片
original_img = Image.open(input_path).convert("RGBA")
watermark_img = Image.open(watermark_path).convert("RGBA")
@ -47,20 +53,27 @@ def add_image_watermark(input_path, watermark_path, output_path):
watermark_img = watermark_img.rotate(random.uniform(-180, 180))
# 合并原始图片和水印图片并将结果转换为RGB模式
original_img.paste(watermark_img, (math.ceil(original_width - original_width/2.6),
math.ceil(original_height-original_height/2.6)), watermark_img)
original_img.paste(
watermark_img,
(
math.ceil(original_width - original_width / 2.6),
math.ceil(original_height - original_height / 2.6),
),
watermark_img,
)
# 保存水印后的图片
original_img.save(output_path)
def add_pdf_watermark(intput_file, watermark_path, output_path):
''' PDF添加印章 '''
"""PDF添加印章"""
stamp = PdfReader(watermark_path).pages[0]
writer = PdfWriter(clone_from=intput_file)
for page in writer.pages:
page.merge_transformed_page(
stamp, Transformation().translate(980, 60).scale(0.37))
stamp, Transformation().translate(980, 60).scale(0.37)
)
writer.write(output_path)
@ -76,8 +89,7 @@ class CustomMessageBox(Toplevel):
# 设置了宽和高
self.width = width
self.height = height
self.geometry(
f'{width}x{height}+{master.winfo_x()}+{master.winfo_y()}')
self.geometry(f"{width}x{height}+{master.winfo_x()}+{master.winfo_y()}")
self.grab_set() # 使得对话框不会在点击窗口之外的地方时关闭
self.wait_window(self) # 等待对话框关闭
@ -86,21 +98,23 @@ class CustomMessageBox(Toplevel):
if __name__ == "__main__":
multi_files = [] # 多选的文件
dir_files = [] # 文件夹中的文件
water_path = '' # 印章路径
tmp_water = '' # 当为图片时删除临时生成的PDF印章
last_stamped = '' # 最后一个添加印章后的文件
water_path = "" # 印章路径
tmp_water = "" # 当为图片时删除临时生成的PDF印章
last_stamped = "" # 最后一个添加印章后的文件
print(print(get_os()))
def reset():
global multi_files, dir_files, water_path, tmp_water
multi_files = []
dir_files = []
water_path = ''
tmp_water = ''
lable_dir.config(text='')
lable_files.config(text='')
lable_stamp.config(text='')
label_create.config(text='')
button_create.config(state='disabled')
water_path = ""
tmp_water = ""
lable_dir.config(text="")
lable_files.config(text="")
lable_stamp.config(text="")
label_create.config(text="")
button_create.config(state="disabled")
button_opendir.place_forget()
button_openfile.place_forget()
@ -111,17 +125,19 @@ if __name__ == "__main__":
def check_status():
# 如果文件和水印都选择便启用水印生成按钮,否则禁用
if ((lable_files.cget('text') != '' or lable_dir.cget('text') != '') and lable_stamp.cget('text') != ''):
button_create.config(state='normal')
if (
lable_files.cget("text") != "" or lable_dir.cget("text") != ""
) and lable_stamp.cget("text") != "":
button_create.config(state="normal")
else:
button_create.config(state='disabled')
button_create.config(state="disabled")
def select_files(extensions=['pdf', 'png', 'jpeg', 'jpg']):
def select_files(extensions=["pdf", "png", "jpeg", "jpg"]):
Tk().withdraw()
files = askopenfiles()
# 检测文件类型
for item in files:
file_extension = item.name.split('.')[-1].lower()
file_extension = item.name.split(".")[-1].lower()
if file_extension not in extensions:
CustomMessageBox(root, "无效的文件类型。")
select_files()
@ -129,9 +145,9 @@ if __name__ == "__main__":
paths = [(item.name) for item in files]
global multi_files
multi_files = paths
str = ','.join(paths)
str = ",".join(paths)
if len(str) >= 50:
str = str[:50] + '...'
str = str[:50] + "..."
lable_files.config(text=str)
check_status()
@ -143,21 +159,21 @@ if __name__ == "__main__":
global dir_files
dir_files = items
if len(folder_path) >= 50:
folder_path = str[:50] + '...'
folder_path = str[:50] + "..."
lable_dir.config(text=folder_path)
check_status()
def select_file(label, extensions=['png', 'jpeg', 'jpg']):
def select_file(label, extensions=["png", "jpeg", "jpg"]):
Tk().withdraw()
file_path = filedialog.askopenfilename()
if file_path:
file_extension = file_path.split('.')[-1].lower()
file_extension = file_path.split(".")[-1].lower()
if file_extension in extensions:
# 隐藏操作按钮
button_opendir.place_forget()
button_openfile.place_forget()
if len(file_path) >= 50:
file_path = str[:50] + '...'
file_path = str[:50] + "..."
label.config(text=file_path)
# 检查水印生成按键可用状态
check_status()
@ -171,7 +187,12 @@ if __name__ == "__main__":
for root, dirs, files in os.walk(dir_path):
for file in files:
# 检查文件是否是PDF或图片
if file.endswith('.pdf') or file.endswith('.png') or file.endswith('.jpg') or file.endswith('.jpeg'):
if (
file.endswith(".pdf")
or file.endswith(".png")
or file.endswith(".jpg")
or file.endswith(".jpeg")
):
# 如果是,则将其完整路径添加到列表中
file_list.append(os.path.join(root, file))
return file_list
@ -181,31 +202,30 @@ if __name__ == "__main__":
name, suffix = os.path.splitext(baseaname)
dir_path = os.path.dirname(file_path)
# # 判断目标文件是图片还是PDF
if suffix.lower() == '.pdf':
if suffix.lower() == ".pdf":
global tmp_water
# 如果水印是图片先转成PDF
if tmp_water == '':
if water_path.split('.')[-1].lower() != 'pdf':
if tmp_water == "":
if water_path.split(".")[-1].lower() != "pdf":
tmp_water = img_to_pdf(water_path)
out_path = os.path.join(
dir_path, 'output', name + '_watered' + suffix)
out_path = os.path.join(dir_path, "output", name + "_watered" + suffix)
check_output(out_path)
add_pdf_watermark(file_path, tmp_water, out_path)
else:
out_path = os.path.join(
dir_path, 'output', name + '_watered' + '.png')
out_path = os.path.join(dir_path, "output", name + "_watered" + ".png")
check_output(out_path)
add_image_watermark(file_path, water_path, out_path)
# 显示操作按钮
global last_stamped
last_stamped = out_path
label_create.config(text='生成成功:')
label_create.place(x=120, y=4*padding_y,
width=80, height=lable_height)
button_openfile.place(x=200, y=4*padding_y,
width=button_width, height=button_height)
button_opendir.place(x=280, y=4*padding_y,
width=button_width, height=button_height)
label_create.config(text="生成成功:")
label_create.place(x=120, y=4 * padding_y, width=80, height=lable_height)
button_openfile.place(
x=200, y=4 * padding_y, width=button_width, height=button_height
)
button_opendir.place(
x=280, y=4 * padding_y, width=button_width, height=button_height
)
def multi_watermask():
global multi_files, dir_files, tmp_water
@ -214,18 +234,24 @@ if __name__ == "__main__":
for item in selected_files:
add_watermask(item, water_path)
# 删除临时PDF印章
if tmp_water != '':
if tmp_water != "":
os.remove(tmp_water)
tmp_water = ''
tmp_water = ""
def open_dirname():
global last_stamped
dir_name = os.path.dirname(last_stamped)
os.startfile(dir_name)
if get_os == "Windows":
os.startfile(dir_name)
else:
subprocess.run(["open", dir_name])
def open_file():
global last_stamped
os.startfile(last_stamped)
if get_os == "Windows":
os.startfile(last_stamped)
else:
subprocess.run(["open", last_stamped])
def get_path(relative_path):
try:
@ -257,38 +283,42 @@ if __name__ == "__main__":
root.geometry("{}x{}+{}+{}".format(500, 300, x_pos, y_pos))
# 选择文件-多选
button_files = Button(root, text="选择文件", command=select_files)
button_files.place(x=button_x, y=padding_y, width=button_width,
height=button_height)
button_files.place(
x=button_x, y=padding_y, width=button_width, height=button_height
)
lable_files = Label(root, text="")
lable_files.place(x=label_x, y=padding_y,
width=label_width, height=lable_height)
lable_files.place(x=label_x, y=padding_y, width=label_width, height=lable_height)
# 选择目录
button_dir = Button(root, text="选择目录", command=select_dir)
button_dir.place(x=button_x, y=2*padding_y,
width=button_width, height=button_height)
button_dir.place(
x=button_x, y=2 * padding_y, width=button_width, height=button_height
)
lable_dir = Label(root, text="")
lable_dir.place(x=label_x, y=2*padding_y,
width=label_width, height=lable_height)
lable_dir.place(x=label_x, y=2 * padding_y, width=label_width, height=lable_height)
# 选择公章
button_stamp = Button(root, text="选择公章", command=lambda: select_file(lable_stamp,
extensions=['png', 'jpeg', 'jpg']))
button_stamp.place(x=button_x, y=3*padding_y,
width=button_width, height=button_height)
lable_stamp = Label(root, text=get_path('waters/stamp.png'))
lable_stamp.place(x=label_x, y=3*padding_y,
width=label_width, height=lable_height)
button_stamp = Button(
root,
text="选择公章",
command=lambda: select_file(lable_stamp, extensions=["png", "jpeg", "jpg"]),
)
button_stamp.place(
x=button_x, y=3 * padding_y, width=button_width, height=button_height
)
lable_stamp = Label(root, text=get_path("waters/stamp.png"))
lable_stamp.place(
x=label_x, y=3 * padding_y, width=label_width, height=lable_height
)
# 预览
label_create = Label(root, text="")
button_opendir = Button(root, text="目录", command=open_dirname)
button_openfile = Button(root, text="预览", command=open_file)
# 添加水印
button_create = Button(
root, text="生成", command=multi_watermask, state='disabled')
button_create.place(x=120, y=6*padding_y,
width=button_width, height=button_height)
button_create = Button(root, text="生成", command=multi_watermask, state="disabled")
button_create.place(
x=120, y=6 * padding_y, width=button_width, height=button_height
)
# 重置
button_reset = Button(root, text="重置", command=reset)
button_reset.place(x=320, y=6*padding_y,
width=button_width, height=button_height)
button_reset.place(x=320, y=6 * padding_y, width=button_width, height=button_height)
root.mainloop()

Binary file not shown.

@ -1,13 +1,21 @@
from PIL import Image
import os
import fitz
img = Image.open('首营资料.jpg').convert("RGBA")
def add_watermask():
file_path = './pdfs/girl.pdf'
water_path = './waters/logo.png'
baseaname = os.path.basename(file_path)
name, suffix = os.path.splitext(baseaname)
out_path = os.path.join(os.path.dirname(file_path),
name + '_watered' + suffix)
pdf_file = fitz.open(file_path)
page = pdf_file[0]
print(page.bound())
# page.insert_image(page.bound(), filename=water_path)
rect = (800, -100, 900, 0)
page.insert_image(rect, filename=water_path)
pdf_file.save(out_path)
pdi = img.info.get('dpi')[0]
img_width, img_heigth = img.size
a4_width = 210
stamp_width = 44
x = stamp_width/a4_width * img_width
print(x)
add_watermask()

Loading…
Cancel
Save