python.tag_dans_JPG_et_PDF/main.py

216 lines
8.9 KiB
Python

'''
Ce script Python prend en entrée un répertoire contenant des fichiers image et des PDF.
1- Pour chaque PDF trouvé, il extrait les pages sous forme d'images dans un répertoire temporaire.
2- Il parcourt toutes les images du répertoire source (défini dans le fichier config.json) et leur ajoute
un filigrame en travers.
3- Chaque imags est ensuite sauvegardée dans un répertoire contenant le nom du filigramme (paramètre text
dans le fichier de configuration config.json)
Configuration:
Toute la configuration (le filigrame et le chemin du répertoire contenant les documents) est à faire dans le
fichier config.json.
filigrame : le nom qui va apparaitre après la phrase : "Document exclusivement destiné à " (cette phrase n'est pas modifiable)
source_directory : le chemin du répertoire contenant les documents dans lesquels il faut ajouter le filigrame.
Il est conseillé de mettre un chemin absolu.
'''
# Press Maj+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.
import os, json, subprocess, zipfile, sys
from PIL import Image, ImageDraw, ImageFont
import piexif
from pdf2image import convert_from_path
def generate_image_with_text(text, font_size=40, line_spacing=50, transparency=0.40):
text = "Document exclusivement destiné à " + text
text = text + " " + text
# Charger une police de caractères
font = ImageFont.truetype("arial.ttf", font_size)
# Obtenir les dimensions du texte
nothing, nothing, text_width, text_height = font.getbbox(text)
# Nombre de lignes de texte à afficher
num_lines = 20
# Calculer la hauteur totale de l'image en tenant compte de l'espacement entre les lignes
total_height = text_height * num_lines + line_spacing * (num_lines - 1)
# Créer une nouvelle image avec fond transparent
text_image = Image.new("RGBA", (text_width, total_height), (0,0,0,0))
# Dessiner le texte sur l'image transparente
text_draw = ImageDraw.Draw(text_image)
for i in range(num_lines):
text_draw.text((0, (text_height + line_spacing) * i), text, fill=(150, 150, 150, int(255 * transparency)), font=font)
# Appliquer une rotation de 45 degrés à l'image masque
rotated_mask = text_image.rotate(45, expand=True)
return rotated_mask
def merge_image_with_text(source_directory, destination_directory, text):
prefix = text.replace(" ", "_")
# Créer le répertoire de destination s'il n'existe pas
os.makedirs(destination_directory, exist_ok=True)
# Liste tous les fichiers dans le répertoire source
files = os.listdir(source_directory)
# Générer l'image avec le texte incliné à 45 degrés
text_image = generate_image_with_text(text)
# Parcourir tous les fichiers du répertoire source
for file in files:
# Vérifier si le fichier est une image
if file.lower().endswith((".jpg", ".jpeg", ".png", ".bmp")):
# Chemin complet de l'image source
source_image_path = os.path.join(source_directory, file)
# Charger l'image source
source_image = Image.open(source_image_path).convert("RGBA")
# Calculer les coordonnées de collage pour centrer l'image source sur text_image
paste_x = (source_image.width - text_image.width) // 2
paste_y = (source_image.height - text_image.height) // 2
# Créer une copie de l'image source pour éviter de la modifier
merged_image = source_image.copy()
# Coller l'image contenant du texte au milieu de l'image source
merged_image.paste(text_image, (paste_x, paste_y), text_image)
# Convertir l'image en mode RVB avant de l'enregistrer au format JPEG
merged_image = merged_image.convert("RGB")
# Récupérer les données EXIF de l'image source
exif_data = source_image.info.get("exif")
# Si des données EXIF existent, les convertir en dictionnaire
if exif_data:
exif_dict = piexif.load(exif_data)
# Ajouter ou remplacer le tag EXIF "ImageDescription" avec le texte spécifié
exif_dict["0th"][270] = "Document exclusivement destiné à " + text
else:
exif_dict = {}
# Convertir le dictionnaire EXIF en données binaires
exif_bytes = piexif.dump(exif_dict)
# Enregistrer l'image fusionnée dans le répertoire de destination
output_image_path = os.path.join(destination_directory, f"{prefix}{file}")
merged_image.save(output_image_path, exif=exif_bytes)
def extract_pdf_pages(pdf_path, text):
# Création du répertoire temporaire
destination_directory = os.path.join(os.path.dirname(pdf_path), "temp")
# Créer le répertoire de destination s'il n'existe pas
os.makedirs(destination_directory, exist_ok=True)
# Convertir chaque page du PDF en image
pages = convert_from_path(pdf_path)
# Extraire le nom du fichier PDF sans l'extension
pdf_filename = os.path.splitext(os.path.basename(pdf_path))[0]
for i, page in enumerate(pages):
filename = f"{pdf_filename}_page_{i+1}.jpg"
output_path = os.path.join(destination_directory, filename)
page.save(output_path, "JPEG")
def process_pdf_files(source_directory, text):
# Parcourir tous les fichiers du répertoire source
for file in os.listdir(source_directory):
# Vérifier si le fichier est un PDF
if file.lower().endswith(".pdf"):
# Chemin complet du fichier PDF
pdf_path = os.path.join(source_directory, file)
# Convertir le PDF en images
extract_pdf_pages(pdf_path, text)
def load_config():
with open("./config.json") as f:
config = json.load(f)
return config
def open_in_file_explorer(directory):
# Vérifier si le répertoire existe
if os.path.exists(directory):
# Ouvrir l'explorateur de fichiers avec le répertoire spécifié
subprocess.Popen(['explorer', directory])
else:
print("Le répertoire spécifié n'existe pas.")
def create_original_files_directory():
config = load_config()
original_files_directory = config.get("source_directory")
if os.path.isdir(original_files_directory):
return
else:
temp_directory = os.path.join(os.getcwd(), f"Original_Files")
os.makedirs(temp_directory)
print(f"Répertoire de travail créé à l'emplacement : {temp_directory}")
# Mettre à jour le chemin du répertoire dans le fichier de configuration
config["source_directory"] = temp_directory
with open("config.json", "w") as f:
json.dump(config, f, indent=4)
print(f"Sauvegarde de la configuration OK")
print(f"Il ne reste plus qu'à mettre les fichiers originaux dans le répertoire ", temp_directory,"' et relancer le script.")
sys.exit(1) # Arrête le script avec un code d'erreur non nul
def is_key_defined_in_json(json_file, key):
with open(json_file, 'r') as f:
data = json.load(f)
return key in data
def zip_directory(directory, zip_file):
with zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED) as zipf:
for root, _, files in os.walk(directory):
for file in files:
file_path = os.path.join(root, file)
zipf.write(file_path, os.path.relpath(file_path, directory))
if __name__ == '__main__':
# Creation du répertoire sources pour mettre les documents
create_original_files_directory()
# Lecture de la configuration
config = load_config()
text = config["filigrame"]
source_directory = config["source_directory"]
destination_directory = os.path.join(source_directory, text.replace(" ", "_"))
temp_directory = os.path.join(source_directory, "temp")
# Extrait les pages des pdf
try:
print("Extrait les pages des pdf")
process_pdf_files(source_directory, text)
# Rajoute le tag dans les images des pages du pdf
print("Rajoute le tag dans les images des pages du pdf")
merge_image_with_text(temp_directory, destination_directory, text)
except:
print(f"Aucun fichier PDF")
# Rajoute le tag sur les images du répertoire courant
try:
print("Rajoute le tag sur les images du répertoire courant")
merge_image_with_text(source_directory, destination_directory, text)
# Ouverture du répertoire contenant toutes les images tagées
open_in_file_explorer(destination_directory)
# Compression du répertoire
if( is_key_defined_in_json("config.json", "zipfile")):
fichierZip = os.path.join(config["zipfile"], text.replace(" ", "_") + ".zip")
print("Compression du répertoire et sauvegarde dans ", fichierZip)
zip_directory(destination_directory, fichierZip)
except:
print(f"Aucune image à taguer")