Initialisation des systèmes...

Baptiste.Dev
Retour aux projets
Projet Perso★ Featured

PNG to SVG Convertor

Outil en ligne gratuit de conversion PNG vers SVG vectoriel avec détection automatique des couleurs, gradients et suppression de fond.

PNG to SVG Convertor

PNG to SVG Convertor

Outil en ligne gratuit pour convertir des images PNG en SVG vectoriel — disponible sur png2svg.baptiste-vidal.fr.


#D'où vient l'idée ?

Au boulot, à l'école et dans mes side projects, j'avais souvent besoin d'icônes en SVG pour éviter toute perte de qualité. Le problème : chaque site de conversion en ligne donnait des résultats médiocres, et quand je demandais à une IA de le faire, il fallait y passer des dizaines de minutes pour un résultat pas terrible.

Je me suis dit que faire mon propre script serait plus efficace — un outil qui priorise la qualité du résultat à la vitesse d'exécution.


#Timeline

PériodeÉtape
Lundi 24 mars 2026Début du développement. Approche full vibe coding pour un résultat rapide, mais cadré par moi-même.
Mardi 25 marsFin du dev + mise en production sur png2svg.baptiste-vidal.fr.
Mercredi 26 marsPost LinkedIn pour montrer la création. Retours d'utilisateurs avec des images qui ne convertissaient pas correctement.
Mercredi soirReprise du dev, patch appliqué et déployé le soir même.
DepuisL'app est en production, disponible au grand public, et n'a pas bougé.

Projet réalisé en solo (ou en duo avec Claude Code).

Hébergé sur l'infra Voyager3, développée avec mes deux potes — la même que Speakzy.


#Stack technique

CoucheTechnologies
BackendPython Flask 3, Gunicorn (2 workers, 4 threads)
Traitement d'imagePillow (I/O, quantization), OpenCV (filtrage, morphologie), potrace (vectorisation), NumPy
FrontendHTML5, CSS3 (variables CSS), JavaScript vanilla
SécuritéFlask-WTF (CSRF), Flask-Limiter (rate limiting)
DéploiementDocker (Python 3.11-slim), Gunicorn

#Comment ça marche

La conversion suit un pipeline en plusieurs étapes :

  1. Upload — Drag & drop ou sélection de fichier, validation côté client (PNG, max 10 Mo)
  2. Prétraitement — Filtrage bilatéral pour débruiter tout en préservant les bords
  3. Analyse des couleurs — Détection automatique des couleurs uniques ou quantification manuelle (0 à 256 couleurs)
  4. Extraction des couches — Chaque couleur devient un masque binaire séparé
  5. Vectorisation — L'algorithme potrace trace les contours de chaque masque en courbes SVG
  6. Gradients — Détection optionnelle de gradients linéaires dans 4 directions
  7. Nettoyage — Suppression automatique du fond, fusion des couleurs similaires
  8. Résultat — SVG propre avec un <path> par couleur, trié par taille

La conversion tourne dans un subprocess isolé avec timeout de 60 secondes pour éviter les blocages.

Calibrage interne

Sous le capot, le moteur de conversion s'appuie sur 8 paramètres internes (nombre de couleurs, seuils de fusion, force de débruitage, upscale, détection de gradients...) que j'ai calibrés pour obtenir le meilleur résultat possible sans que l'utilisateur ait à s'en soucier. L'idée est que l'outil donne un résultat propre dès le premier essai.

Un exemple : la fusion adaptative des couleurs. Les petites zones (texte, détails fins) utilisent un seuil agressif (2.5× le seuil normal) pour éviter les artefacts, tandis que les grandes zones (logos, formes) gardent une fidélité stricte aux couleurs d'origine.


#Sécurité

  • CSRF : Protection via Flask-WTF, token dans le meta tag
  • Rate limiting : 10 requêtes par minute par IP
  • Taille max : 10 Mo par fichier, 4096×4096 pixels max
  • Bombe de décompression : Limite Pillow à 16M pixels
  • Headers HTTP : CSP strict, X-Frame-Options DENY, HSTS, nosniff
  • Cookies : HttpOnly, Secure, SameSite=Lax
  • Nettoyage : Fichiers supprimés immédiatement après conversion + cleanup auto toutes les 5 minutes

#Difficultés rencontrées

La difficulté principale a été de comprendre le fonctionnement interne du format SVG et de bien paramétrer les bibliothèques de vectorisation. Calibrer le nombre de couleurs optimal, savoir quand appliquer un gradient ou pas, et ajuster les seuils de fusion pour que le résultat soit fidèle à l'image d'origine sans être trop complexe — c'est un équilibre subtil qui a demandé pas mal d'itérations.

Les retours LinkedIn ont été précieux : des utilisateurs ont envoyé des images que le convertisseur ne gérait pas, ce qui m'a permis d'identifier et corriger les cas limites rapidement.


#Ce que j'ai appris

  • Vibe coding encadré : Utiliser l'IA comme accélérateur tout en gardant le contrôle sur l'architecture et les choix techniques
  • Traitement d'image : Comprendre les algorithmes de vectorisation (potrace), la quantification de couleurs et les opérations morphologiques
  • Feedback loop : Publier rapidement, récolter du feedback réel sur LinkedIn, et itérer le soir même
  • Subprocess isolation : Faire tourner du traitement lourd dans un process séparé avec timeout pour ne pas bloquer le serveur