[PS CC2025] Печать на 200 стр

izrukvruki

Топикстартер
15 лет на форуме
Сообщения
2 003
Реакции
365
Есть бухгалтерский документ pdf с большим кол-вом страниц - 100-300 стр.
Нужно на каждую страницу в нижним левом углу вставить печать организации и печать "Копия верна".
Как это можно автоматизировать?
 
Quite Imposing
Indesign
Preps


Уж и не знаю, продолжать ли...
 
Последнее редактирование:
Штатными средствами Акробата
1779953252734.png
 
  • Спасибо
Реакции: George и zollinger
watermark в Acrobat, кажется, нужен именно для таких задач
 
Фотошоп тут причем, раздел перепутали?
 
Quite Imposing
 

Вложения

  • 2026-05-28 10-32-57 Stick on PDF pages.jpg
    2026-05-28 10-32-57 Stick on PDF pages.jpg
    133.5 КБ · Просм.: 16
И я, наверняка, ещё что-то забыл.
Так и есть! :D
Ну, тогда и так можно:

Python:
import os
import tkinter as tk
from tkinter import filedialog, messagebox
import fitz  # Библиотека PyMuPDF

def mm_to_points(mm):
    """Конвертирует миллиметры в пункты PDF (1 дюйм = 25.4 мм = 72 пункта)."""
    return (mm / 25.4) * 72

def process_pdf():
    # 1. Выбор исходного PDF-файла
    pdf_path = filedialog.askopenfilename(
        title="Выберите исходный PDF-документ",
        filetypes=[("PDF файлы", "*.pdf")],
    )
    if not pdf_path:
        return
    # 2. Выбор изображения
    img_path = filedialog.askopenfilename(
        title="Выберите изображение для вставки",
        filetypes=[
            ("Изображения", "*.png *.jpg *.jpeg *.bmp"),
            ("Все файлы", "*.*"),
        ],
    )
    if not img_path:
        return
    # 3. Считывание координат и размеров из полей ввода
    try:
        x_mm = float(entry_x.get())
        y_mm = float(entry_y.get())
        w_mm = float(entry_w.get())
        h_mm = float(entry_h.get())
    except ValueError:
        messagebox.showerror(
            "Ошибка", "Пожалуйста, введите корректные числа в поля координат."
        )
        return
    # Перевод мм в пункты PDF
    x1 = mm_to_points(x_mm)
    y1 = mm_to_points(y_mm)
    x2 = x1 + mm_to_points(w_mm)
    y2 = y1 + mm_to_points(h_mm)
    rect = fitz.Rect(x1, y1, x2, y2)
    # 4. Обработка PDF
    try:
        doc = fitz.open(pdf_path)
        for page in doc:
            # 1. Сначала вставляем картинку стандартным методом страницы
            page.insert_image(rect, filename=img_path)
            
            # 2. Создаем невидимую аннотацию-подложку, которая принудительно включает
            # режим Multiply для всех новых графических объектов на этой странице
            annot = page.add_rect_annot(rect)
            
            # Настраиваем аннотацию (делаем её прозрачной, но задаем режим смешивания)
            annot.set_colors(stroke=None, fill=None)  # Без цвета и рамок
            annot.set_opacity(1.0)
            
            # Прописываем режим Multiply напрямую в словарь аннотации
            # Это включает поддержку композитинга на странице в Acrobat и других вьюверах
            annot_xref = annot.xref
            if annot_xref > 0:
                doc.xref_set_key(annot_xref, "BM", "/Multiply")
            
            annot.update()
        # Формируем имя для сохранения нового файла
        dir_name, file_name = os.path.split(pdf_path)
        output_path = os.path.join(dir_name, "ready_" + file_name)
        # Сохраняем с оптимизацией структуры
        doc.save(output_path, garbage=3, deflate=True)
        doc.close()
        messagebox.showinfo(
            "Успех", f"Файл успешно сохранен как:\n{output_path}"
        )
    except Exception as e:
        messagebox.showerror(
            "Ошибка обработки", f"Произошла ошибка при изменении PDF:\n{str(e)}"
        )

# --- Создание графического интерфейса ---
root = tk.Tk()
root.title("Вставка изображения в PDF (Multiply)")
root.geometry("380x280")
root.resizable(False, False)
frame = tk.LabelFrame(root, text=" Настройки положения (в мм) ")
frame.pack(padx=15, pady=15, fill="x", ipady=5)
# Поля ввода
tk.Label(frame, text="Отступ слева (X):").grid(
    row=0, column=0, sticky="w", pady=5, padx=10
)
entry_x = tk.Entry(frame, width=10)
entry_x.insert(0, "20")  # Значение по умолчанию
entry_x.grid(row=0, column=1, pady=5)
tk.Label(frame, text="Отступ сверху (Y):").grid(
    row=1, column=0, sticky="w", pady=5, padx=10
)
entry_y = tk.Entry(frame, width=10)
entry_y.insert(0, "20")
entry_y.grid(row=1, column=1, pady=5)
tk.Label(frame, text="Ширина картинки:").grid(
    row=2, column=0, sticky="w", pady=5, padx=10
)
entry_w = tk.Entry(frame, width=10)
entry_w.insert(0, "50")
entry_w.grid(row=2, column=1, pady=5)
tk.Label(frame, text="Высота картинки:").grid(
    row=3, column=0, sticky="w", pady=5, padx=10
)
entry_h = tk.Entry(frame, width=10)
entry_h.insert(0, "50")
entry_h.grid(row=3, column=1, pady=5)
# Кнопка запуска процесса
btn_start = tk.Button(
    root,
    text="Выбрать файлы и запустить",
    command=process_pdf,
    bg="#bfbfbf",
    fg="black",
    font=("Segoe UI", 10),
)
btn_start.pack(fill="x", padx=15, pady=5, ipady=5)
root.mainloop()
 
Последнее редактирование: