Vicy_Publique/utils/card_generator.py

128 lines
4.5 KiB
Python
Raw Permalink Normal View History

2026-08-16 19:37:15 +02:00
import os
import aiohttp
import discord
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont
class CardGenerator:
def __init__(self):
self.session = None
self.template = None
self.watermark = None
self.font_regular = None
self.font_bold = None
self.font_large = None
self.create_template()
def create_template(self):
try:
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
CI_path = os.path.join(base_dir, "ressources", "assets", "CIITAL.png")
2026-08-16 19:37:15 +02:00
if not os.path.exists(CI_path):
raise FileNotFoundError(f"Image de fond introuvable : {CI_path}")
# Chargement de l'image de base
self.template = Image.open(CI_path).convert("RGBA")
self.template = self.template.resize((800, 500))
# Vérifier que l'image a bien été chargée
if self.template is None:
raise ValueError("L'image de fond n'a pas été chargée correctement.")
# Chargement des polices
try:
self.font_regular = ImageFont.load_default()
self.font_bold = ImageFont.load_default()
self.font_large = ImageFont.load_default()
except Exception as e:
print(f"Erreur lors du chargement des polices: {e}")
self.font_regular = None
self.font_bold = None
self.font_large = None
# Créer un filigrane transparent
self.watermark = Image.new('RGBA', (800, 500), (255, 255, 255, 0))
watermark_draw = ImageDraw.Draw(self.watermark)
for i in range(0, 800, 100):
for j in range(0, 500, 100):
watermark_draw.text((i, j), "", fill=(200, 200, 200, 100))
except Exception as e:
print(f"Erreur lors de la création du template: {e}")
self.template = None
self.watermark = None
async def get_session(self):
if self.session is None:
self.session = aiohttp.ClientSession()
return self.session
async def download_avatar(self, user):
if not user.avatar:
return Image.new('RGBA', (200, 200), (128, 128, 128, 255))
try:
session = await self.get_session()
async with session.get(str(user.avatar.url)) as response:
if response.status == 200:
avatar_data = await response.read()
return Image.open(BytesIO(avatar_data)).convert('RGBA')
except Exception as e:
print(f"Erreur lors du téléchargement de l'avatar: {e}")
return Image.new('RGBA', (200, 200), (128, 128, 128, 255))
async def create_identity_card(self, user, identity_data):
if not self.template:
self.create_template()
if not self.template:
raise Exception("Impossible de créer le template")
card = self.template.copy()
draw = ImageDraw.Draw(card)
try:
# Photo de profil
avatar = await self.download_avatar(user)
avatar = avatar.resize((200, 200), Image.LANCZOS)
mask = Image.new('L', avatar.size, 0)
mask_draw = ImageDraw.Draw(mask)
mask_draw.ellipse((0, 0, 200, 200), fill=255)
card.paste(avatar, (50, 120), mask)
# Informations personnelles
text_positions = {
'nom': (328, 169),
'prenom': (329, 212),
'date_naissance': (329, 254),
'lieu_naissance': (489, 169),
'sexe': (511, 212),
'date_expiration': (26, 408)
}
for field, pos in text_positions.items():
value = str(identity_data[field])
draw.text(pos,
value,
fill='black',
font=self.font_bold if field in ['nom', 'prenom'] else self.font_regular)
if self.watermark:
card.paste(self.watermark, (0, 0), self.watermark)
buffer = BytesIO()
card.save(buffer, format='PNG')
buffer.seek(0)
return buffer
except Exception as e:
print(f"Erreur lors de la création de la carte: {e}")
raise
async def cleanup(self):
if self.session:
await self.session.close()
self.session = None