Je suis en train de développer un petit logiciel en Python pour optimiser mon workflow, et j’aurais besoin de vos lumières.
Mon objectif est de créer un programme qui m’aide à vérifier des plans réalisés sur Illustrator, exportés en PDF. Dans un premier temps, je souhaite que mon programme puisse :
J’ai pu avancer un peu grâce à l’aide d’un assistant IA, mais je rencontre un problème que je n’arrive pas à résoudre :
J’aimerais que mon programme puisse importer correctement n’importe quel fichier PDF, peu importe sa provenance (dossier, sous-dossier, Téléchargements) et peu importe leur quantité.
Si quelqu’un a une idée pour résoudre ce problème, je suis preneur ! Merci d’avance pour votre aide. 😊
import tkinter as tk
from tkinter import Label, Frame, Toplevel, Canvas, Scrollbar
from tkinterdnd2 import DND_FILES, TkinterDnD
import PyPDF2
import fitz # PyMuPDF
import os
from PIL import Image, ImageTk
from tkinter import messagebox
# Dimensions des formats A en mm
formats_a = {
"A0": (841, 1189),
"A1": (594, 841),
"A2": (420, 594),
"A3": (297, 420),
"A4": (210, 297),
"A5": (148, 210)
}
def drop(event):
# Extraire les chemins des fichiers déposés
raw_paths = event.data.splitlines() # Utiliser splitlines pour gérer les chemins sur plusieurs lignes
# Nettoyer les chemins
file_paths = []
for path in raw_paths:
# Nettoyage des chemins pour enlever les accolades et autres caractères indésirables
paths = path.strip().strip("{}").replace("} {", "\n").splitlines() # Remplacer "} {" par un saut de ligne
for p in paths:
p = p.strip().strip("{}").strip('"').strip("'") # Nettoyage des chemins
if p: # Ajout du chemin nettoyé si valide
file_paths.append(os.path.normpath(p)) # Normaliser le chemin
print("Chemins analysés après nettoyage :", file_paths) # Debug
pdf_files = []
# Vérification des chemins pour les fichiers PDF
for path in file_paths:
print("Chemin analysé :", path) # Debug
if os.path.isfile(path) and path.lower().endswith(('.pdf', '.PDF')): # Si c'est un fichier PDF
print("C'est un fichier PDF :", path) # Debug
pdf_files.append(path)
elif os.path.isdir(path): # Si c'est un dossier, chercher les fichiers PDF dedans
print("C'est un dossier :", path) # Debug
for root, _, files in os.walk(path):
for file in files:
full_file_path = os.path.join(root, file)
if full_file_path.lower().endswith(('.pdf', '.PDF')): # Si c'est un PDF
pdf_files.append(full_file_path)
print(f"Fichier PDF ajouté depuis le dossier : {full_file_path}") # Debug
else:
print("Chemin invalide ou pas un PDF :", path) # Debug
print("Liste finale des fichiers PDF :", pdf_files) # Debug
# Si des fichiers PDF ont été trouvés, traiter l'affichage
if pdf_files:
show_file_info(pdf_files) # Afficher les fichiers PDF dans la fenêtre
else:
messagebox.showerror("Erreur", "Aucun fichier PDF valide trouvé.")
def get_pdf_dimensions(file_path):
try:
with open(file_path, "rb") as file:
reader = PyPDF2.PdfReader(file)
# Obtenir la première page
page = reader.pages[0]
# Obtenir les dimensions de la page
width = float(page.mediabox.width)
height = float(page.mediabox.height)
# Convertir les dimensions de points à millimètres (1 point = 0.352778 mm)
width_mm = width * 0.352778
height_mm = height * 0.352778
# Déterminer le format et l'orientation
format_name, orientation = detect_format(width_mm, height_mm)
return f"{width_mm:.2f} mm x {height_mm:.2f} mm", format_name, orientation
except Exception as e:
return f"Erreur lors de la lecture du PDF: {str(e)}", None, None
def detect_format(width, height):
for format_name, (format_width, format_height) in formats_a.items():
if (abs(width - format_width) < 5 and abs(height - format_height) < 5) or \
(abs(width - format_height) < 5 and abs(height - format_width) < 5):
if width > height:
orientation = "Horizontal"
else:
orientation = "Vertical"
return format_name, orientation
return "Inconnu", "Inconnu"
def show_file_info(file_paths):
# Création d'une nouvelle fenêtre pour afficher les informations des fichiers PDF
file_window = Toplevel(root)
file_window.title("Informations sur les fichiers PDF")
canvas = Canvas(file_window, width=400)
scrollbar = Scrollbar(file_window, orient="vertical", command=canvas.yview)
canvas.configure(yscrollcommand=scrollbar.set)
scrollbar.pack(side="right", fill="y")
canvas.pack(side="left", fill="both", expand=True)
info_frame = Frame(canvas)
canvas.create_window((0, 0), window=info_frame, anchor="nw")
for file_path in file_paths:
file_name = os.path.basename(file_path)
# Ici vous devez définir la fonction `get_pdf_dimensions` pour extraire les dimensions du PDF
dimensions, format_name, orientation = get_pdf_dimensions(file_path)
label_name = Label(info_frame, text=f"Nom du fichier : {file_name}")
label_name.pack(padx=5, pady=2)
label_dimensions = Label(info_frame, text=f"Dimensions : {dimensions}")
label_dimensions.pack(padx=5, pady=2)
label_format_orientation = Label(info_frame, text=f"Format : {format_name} ({orientation})")
label_format_orientation.pack(padx=5, pady=2)
display_pdf_image(file_path, info_frame)
separator = Label(info_frame, text="-------------------------")
separator.pack(pady=5)
info_frame.update_idletasks()
canvas.config(scrollregion=canvas.bbox("all"))
def _on_mouse_wheel(event):
canvas.yview_scroll(-1 * (event.delta // 120), "units")
canvas.bind_all("<MouseWheel>", _on_mouse_wheel)
def display_pdf_image(pdf_path, parent_frame):
try:
pdf_document = fitz.open(pdf_path)
page = pdf_document[0]
zoom_x = 2.0
zoom_y = 2.0
matrix = fitz.Matrix(zoom_x, zoom_y)
pix = page.get_pixmap(matrix=matrix)
high_res_img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
max_width = 200
max_height = 200
small_img = high_res_img.copy()
small_img.thumbnail((max_width, max_height), Image.LANCZOS)
small_img_tk = ImageTk.PhotoImage(small_img)
label = Label(parent_frame, image=small_img_tk)
label.image = small_img_tk
label.pack(pady=10)
def open_fullscreen_preview(event):
preview_window = Toplevel(root)
preview_window.title("Aperçu")
preview_window.attributes("-fullscreen", True)
preview_window.configure(bg="black")
screen_width = preview_window.winfo_screenwidth()
screen_height = preview_window.winfo_screenheight()
img_width, img_height = high_res_img.size
if img_width > img_height:
new_width = screen_width
new_height = int(new_width * img_height / img_width)
else:
new_height = screen_height
new_width = int(new_height * img_width / img_height)
img_resized = high_res_img.resize((new_width, new_height), Image.LANCZOS)
high_res_img_tk = ImageTk.PhotoImage(img_resized)
label_preview = Label(preview_window, image=high_res_img_tk)
label_preview.image = high_res_img_tk
label_preview.pack(fill="both", expand=True)
def close_fullscreen_preview(event):
preview_window.destroy()
preview_window.bind("<Button-1>", close_fullscreen_preview)
label.bind("<Button-1>", open_fullscreen_preview)
pdf_document.close()
except Exception as e:
error_label = Label(parent_frame, text=f"Erreur lors de l'affichage de l'image : {e}", fg="red")
error_label.pack()
# Lancer l'application TkinterDnD
root = TkinterDnD.Tk()
root.title("Vérificateur de PDF")
root.geometry("400x400")
drop_area = Label(root, text="Glissez et déposez des fichiers PDF ici", width=50, height=10, bg="lightgrey")
drop_area.pack(padx=20, pady=20)
drop_area.drop_target_register(DND_FILES)
drop_area.dnd_bind('<<Drop>>', drop)
root.mainloop()