xingzi 2 years ago
commit d2e79cbe8e

4
.gitignore vendored

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

@ -0,0 +1,129 @@
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()

Binary file not shown.

Binary file not shown.

@ -0,0 +1,294 @@
import os
import sys
from fpdf import FPDF
from PIL import Image
from tkinter import filedialog
from tkinter import Tk, Button, Label, Toplevel
from tkinter.filedialog import askdirectory, askopenfiles
from pypdf import PdfWriter, PdfReader, Transformation
import math
import random
def check_output(path):
dir_name = os.path.dirname(path)
if False == os.path.exists(dir_name):
pass
# 创建文件夹
os.mkdir(dir_name)
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')
pdf = FPDF()
pdf.add_page()
pdf.image(img_path, x=x, y=y, w=w, h=h)
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")
# 获取原始图片
original_width, original_height = original_img.size
water_width = water_height = math.ceil(38 / 210 * original_width)
# 将水印图片缩放到与原始图片相同的大小
watermark_img = watermark_img.resize((water_width, water_height))
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.save(output_path)
def add_pdf_watermark(intput_file, watermark_path, output_path):
''' 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))
writer.write(output_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__":
multi_files = [] # 多选的文件
dir_files = [] # 文件夹中的文件
water_path = '' # 印章路径
tmp_water = '' # 当为图片时删除临时生成的PDF印章
last_stamped = '' # 最后一个添加印章后的文件
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')
button_opendir.place_forget()
button_openfile.place_forget()
def on_closing():
root.destroy()
root.quit()
exit()
def check_status():
# 如果文件和水印都选择便启用水印生成按钮,否则禁用
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')
def select_files(extensions=['pdf', 'png', 'jpeg', 'jpg']):
Tk().withdraw()
files = askopenfiles()
# 检测文件类型
for item in files:
file_extension = item.name.split('.')[-1].lower()
if file_extension not in extensions:
CustomMessageBox(root, "无效的文件类型。")
select_files()
return
paths = [(item.name) for item in files]
global multi_files
multi_files = paths
str = ','.join(paths)
if len(str) >= 50:
str = str[:50] + '...'
lable_files.config(text=str)
check_status()
def select_dir():
root = Tk()
root.withdraw()
folder_path = askdirectory()
items = recursive_walk(folder_path)
global dir_files
dir_files = items
if len(folder_path) >= 50:
folder_path = str[:50] + '...'
lable_dir.config(text=folder_path)
check_status()
def select_file(label, extensions=['png', 'jpeg', 'jpg']):
Tk().withdraw()
file_path = filedialog.askopenfilename()
if file_path:
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] + '...'
label.config(text=file_path)
# 检查水印生成按键可用状态
check_status()
else:
CustomMessageBox(root, "无效的文件类型。")
select_file()
def recursive_walk(dir_path):
file_list = []
# 遍历指定文件夹
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'):
# 如果是,则将其完整路径添加到列表中
file_list.append(os.path.join(root, file))
return file_list
def add_watermask(file_path, water_path):
baseaname = os.path.basename(file_path)
name, suffix = os.path.splitext(baseaname)
dir_path = os.path.dirname(file_path)
# # 判断目标文件是图片还是PDF
if suffix.lower() == '.pdf':
global tmp_water
# 如果水印是图片先转成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)
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')
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)
def multi_watermask():
global multi_files, dir_files, tmp_water
water_path = lable_stamp.cget("text")
selected_files = list(set(multi_files + dir_files))
for item in selected_files:
add_watermask(item, water_path)
# 删除临时PDF印章
if tmp_water != '':
os.remove(tmp_water)
tmp_water = ''
def open_dirname():
global last_stamped
dir_name = os.path.dirname(last_stamped)
os.startfile(dir_name)
def open_file():
global last_stamped
os.startfile(last_stamped)
def get_path(relative_path):
try:
base_path = sys._MEIPASS
except AttributeError:
base_path = os.path.abspath(".")
return os.path.normpath(os.path.join(base_path, relative_path))
# 主窗口
button_width = 70
button_height = 26
label_width = 300
lable_height = 26
button_x = 50
label_x = 150
button_y = 100
padding_y = 40
root = Tk()
root.title("印章助手")
root.resizable(False, False)
root.protocol("WM_DELETE_WINDOW", on_closing)
# 获取屏幕宽度和高度
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
# 计算窗口的理想位置
x_pos = int((screen_width - 500) / 2)
y_pos = int((screen_height - 300) / 2)
# 设置窗口位置
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)
lable_files = Label(root, text="")
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)
lable_dir = Label(root, text="")
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)
# 预览
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_reset = Button(root, text="重置", command=reset)
button_reset.place(x=320, y=6*padding_y,
width=button_width, height=button_height)
root.mainloop()

@ -0,0 +1,13 @@
from PIL import Image
img = Image.open('首营资料.jpg').convert("RGBA")
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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Loading…
Cancel
Save