QRCodeGenerator
void Genèse()
{
Ce projet est né d'un agacement.
Un QR Code à générer pour un projet, rien de bien méchant. Comme tout le monde, j'ouvre un moteur de recherche, je tape « générateur de QR Code », et là, première page : « Entrez votre email pour continuer », « Créez un compte gratuit », « Inscrivez-vous pour télécharger votre QR Code »…
Il me faut un compte, une adresse mail, parfois même plus, juste pour encoder une URL dans une grille de pixels noirs et blancs ? Je ne parle même pas de ce que ces sites font des données qu'on leur confie — parce qu'un QR Code pour un projet, c'est souvent une URL interne, un lien pas encore public, parfois des infos qu'on ne voudrait surtout pas balancer sur le premier site venu.
J'en ai eu marre. Marre de laisser traîner mon adresse mail sur des services dont je ne sais rien, juste pour un besoin de cinq minutes.
Et c'est là que la curiosité a pris le relais : de toute façon, un QR Code, c'est quoi ? Des motifs, des points, une norme, de la logique. Des trucs que je sais faire. Alors au lieu de nourrir un énième site avec mes données, j'ai ouvert un projet vide, et j'ai décidé d'écrire mon propre générateur. De zéro. En C++17. Chez moi, sur ma machine, où mes données restent.
}
void Description_Du_Projet()
{
}
void Comment_Ça_Marche()
{
Un QR Code, vu de l'intérieur, c'est une petite chaîne de production. Voici le pipeline, étape par étape :
Choisir la taille — Les QR Codes existent en 40 versions (de 21×21 à 177×177 modules). Le code parcourt les versions et prend la plus petite qui peut contenir le texte selon le niveau de correction demandé.
Encoder le texte — Mode octets : indicateur de mode, longueur, données, terminateur, puis du remplissage avec 0xEC et 0x11. Oui, même le remplissage a des valeurs officielles. La norme ne laisse rien au hasard.
Corriger les erreurs — Reed–Solomon. La même idée que pour les CD-ROM : ajouter des octets calculés pour que le code survive aux modules endommagés ou masqués. Ces octets de correction sont calculés, puis entrelacés en blocs.
Dessiner les motifs — Les trois grands carrés de position, les lignes de synchronisation, les petits motifs d'alignement, les informations de format et de version. C'est là que j'ai compris que chaque pixel du coin « vide » a en fait une fonction.
Placer les données — Les codewords sont déposés dans les cellules libres, en zigzag, de droite à gauche, en alternant le sens. Oui, en zigzag. La norme aime bien rendre les choses intéressantes.
Choisir un masque — Huit motifs de masque possibles, appliqués pour éviter les zones trop uniformes qui compliquent la lecture. Le code teste les huit, calcule un score de pénalité, et garde le meilleur. Un petit concours de beauté algorithmique, à chaque génération.
Écrire le PNG — Création d'une image RGBA, avec une échelle réglable (20 pixels par module par défaut) et une marge propre autour du code.
}
void Utilisation()
{
Côté utilisation, c'est volontairement simple :
QRCodeGenerator::GenerateQRCode("QRCode.png", "https://www.lepetitportfolio.fr", CorrectionLevel::M);Une simple ligne, et vous avez un PNG "scannable".
Une surcharge permet aussi de choisir les couleurs RGBA des modules foncés, des modules clairs et du fond. Parce qu'un QR Code tout noir sur blanc, c'est fonctionnel… mais un peu triste. Personnellement, je préfère quand ça matche l'ambiance du site qui l'affiche.
}
void Limites()
{
Ce projet est un prototype. La chaîne de génération complète est là, mais le code contient une incohérence entre les valeurs de l'énumération CorrectionLevel et l'indexation des tables : les niveaux de correction demandés peuvent être mal interprétés. Et pour l'instant, aucun test automatisé de décodage n'est fourni avec le projet.
Concrètement : la mécanique est là, tout semble fonctionner, mais le résultat n'est pas encore garanti conforme. C'est le prochain chantier !
}
void Retour_Personnel()
{
Ce projet, c'est exactement le genre de truc que j'aime : prendre un objet tellement banal qu'on ne le regarde plus, et découvrir qu'il cache une machinerie fascinante — mathématiques de l'information, théorie des codes, arbitrage entre densité et fiabilité.
Reed–Solomon, les masques, le placement en zigzag… tout ça a été conçu pour que le code survive à un coin griffé, une ombre, un café renversé. Il y a quelque chose de plutôt élégant dans cette idée : construire pour que ça marche même quand tout ne se passe pas comme prévu.
Et puis il y a la satisfaction de base : aujourd'hui, quand j'ai besoin d'un QR Code, je le génère en local, sans laisser mon adresse mail derrière moi. Le besoin initial est réglé, et j'ai appris une montagne de choses en le réglant. Le meilleur des deux mondes, quoi.
Et c'est aussi un très bon exercice C++ : architecture en modules séparés (encodage, correction, motifs, placement, masquage, PNG), build CMake propre, surcharge réfléchie. Le genre de projet qui fait progresser sans crier gare.
}
void Amelioration_Possible()
{
Corriger l'incohérence CorrectionLevel pour que les niveaux soient respectés
Ajouter un test de décodage automatisé (générer, décoder, comparer)
Ajouter une interface graphique, pour transformer la bibliothèque en véritable éditeur de QR Code personnalisé : aperçu en temps réel, réglage fin des couleurs, de la marge et de l'échelle, export en un clic
Peut-être un jour : les modes numérique et alphanumérique, pour des codes plus compacts