I. Introduction▲
Un QR code est la représentation graphique d'un message. C'est une sorte de code-barre en deux dimensions. Ledit message peut contenir une URL, un e-mail, un numéro de téléphone, une vCard, etc. Dans la suite, nous nous intéresserons aux messages simples, les messages plus complexes n'étant que des extensions avec une syntaxe particulière.
La plupart des développeurs sont à l'aise avec les QR codes. Ils savent comment les scanner depuis leurs smartphones. De nombreuses « app » sont dédiées à cette fonctionnalité et on en possède souvent plusieurs. Les développeurs savent aussi comment créer des QR codes à l'aide des mêmes « app », des plugins Chrome ou Firefox, ou encore des sites web comme Unitag et SoQR.
En revanche, quand il s'agit de générer soit même un QR code, c'est tout de suite moins drôle, car les algorithmes de calcul sont loin d'être triviaux et la génération d'images, un minimum jolies, n'est pas une compétence très répandue. On pourrait donc penser que la tâche est complexe, voire impossible sans une étude approfondie.
Dans cet article, nous allons d'abord voir comment générer une matrice de modules à l'aide de la bibliothèque Zxing. Dans un second temps, nous verrons comment dessiner des images (belles) à l'aide de Java 2D.
En première approche, un QR code simple ressemble à un carré rempli de gros pixels blancs et noirs. Ces « pixels noirs » sont les « modules » dont je parle plus haut.
I-A. À propos▲
Découvrir une technologie n'est pas chose facile. En aborder plusieurs d'un coup l'est encore moins. Partant de ce constat, cet article a été écrit pour aller à l'essentiel. Les points importants sont présentés dans le corps de l'article et les éléments secondaires, comme la gestion des exceptions, sont expliqués en annexes.
I-B. Avant de commencer▲
Pour écrire ce tutoriel, j'ai utilisé les éléments suivants :
- Java JDK 1.6.0_24-b07 ;
- Eclipse Indigo 3.7 JEE 64b ;
- Maven 3.0.3 ;
- Zxing 2.0.
I-C. Mises à jour▲
1er novembre : ajout du chapitre « Réduction d'adresse », qui propose une piste pour créer des QR codes plus simples à scanner.
27 février 2013 : ajout d'un lien dans les annexes vers l'article « Usages des codes à barres 2D, QR Codes et flashcodes », par Eric POMMEREAU.
II. Découverte du projet d'exemple▲
II-A. Télécharger, installer et importer le projet d'exemple▲
Pour commencer, je vous propose de télécharger le fichier Zip « qr-code-01.zip », contenant un projet Java-Maven d'exemple (vide) qui va nous servir de support pour les fonctionnalités présentées dans la suite de cet article.
Compilez le projet d'exemple et importez-le dans Eclipse (comme expliqué dans le tutoriel « Importer un projet Maven dans Eclipse en 5 minutes ») ou dans l'IDE de votre choix.
Pour suivre ce tutoriel, vous pouvez vous contenter de lire les codes proposés ci-dessous (codes complets en annexes) et de faire confiance aux captures d'écran.
II-B. Ce que fait déjà le projet d'exemple▲
Pour une fois, je vous propose un projet d'exemple qui ne fait rien. C'est un projet Maven vide qui va seulement servir d'enveloppe pour la suite.
III. Action▲
III-A. Maven▲
Durée estimée : 1 minute.
Pour utiliser Zxing, il faut ajouter une dépendance dans le fichier « pom.xml ».
<!-- zxing -->
<dependency>
<groupId>
com.google.zxing</groupId>
<artifactId>
core</artifactId>
<version>
2.0</version>
</dependency>
<dependency>
<groupId>
com.google.zxing</groupId>
<artifactId>
javase</artifactId>
<version>
2.0</version>
</dependency>
Puis relancer une installation Maven.
mvn clean install eclipse:eclipse
En fonction des éléments déjà présents sur le disque dur, le résultat de l'installation Maven devrait ressembler à la trace suivante :
C:\...\qr-code>
mvn clean install eclipse:eclipse
[INFO] Scanning for
projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building qr-code 1
.0
-SNAPSHOT
[INFO] ------------------------------------------------------------------------
...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11
.025s
[INFO] Finished at: Thu Apr 30
20
:59
:22
CEST 2012
[INFO] Final Memory: 10M/53M
[INFO] ------------------------------------------------------------------------
On doit ensuite faire un refresh (touche F5) dans Eclipse pour faire apparaitre Zxing dans la liste des bibliothèques référencées.
III-B. Création des QR codes▲
Durée estimée : 2 minutes.
La génération d'un QR code commence toujours par le calcul de sa matrice, qu'on peut assimiler à un tableau de « 1 » et de « 0 » correspondant aux modules noirs et blancs.
public
class
SimpleQrcodeGenerator {
public
static
void
main
(
String[] args) {
String data =
"Je suis Thierry et je suis gentil."
;
int
size =
400
;
// encode
BitMatrix bitMatrix =
generateMatrix
(
data, size);
}
private
static
BitMatrix generateMatrix
(
String data, int
size) {
BitMatrix bitMatrix =
new
QRCodeWriter
(
).encode
(
data, BarcodeFormat.QR_CODE, size, size);
return
bitMatrix;
}
...
Quand c'est fait, il suffit de dessiner les modules.
public
class
SimpleQrcodeGenerator {
public
static
void
main
(
String[] args) {
...
BitMatrix bitMatrix =
generateMatrix
(
data, size);
String imageFormat =
"png"
;
String outputFileName =
"c:/code/qrcode-01."
+
imageFormat;
// write in a file
writeImage
(
outputFileName, imageFormat, bitMatrix);
}
private
static
void
writeImage
(
String outputFileName, String imageFormat, BitMatrix bitMatrix) {
FileOutputStream fileOutputStream =
new
FileOutputStream
(
new
File
(
outputFileName));
MatrixToImageWriter.writeToStream
(
bitMatrix, imageFormat, fileOutputStream);
fileOutputStream.close
(
);
}
...
Le code complet, avec la gestion des exceptions est donné en annexe.
Cela va donc générer l'image « qrcode-01.png » contenant le message « Je suis Thierry et je suis gentil ».
Voici ce que ça donne lorsque je scanne ce code depuis mon iPhone :
III-C. Un code en couleur▲
Durée estimée : 2 minutes.
C'est bien beau de savoir générer un code, mais ça n'est pas très sexy de se contenter de noir et de blanc. J'ai donc demandé aux développeurs d'Unitag de m'envoyer quelques morceaux de code pour ajouter un peu de couleur.
Je vais donc devoir un peu changer mon code, mais le principe reste le même, avec un peu de contrôles supplémentaires.
public
class
ColoredQrcodeGenerator {
public
static
void
main
(
String[] args) {
String data =
"Je suis Thierry et je suis gentil."
;
// encode
ByteMatrix matrix =
generateMatrix
(
data);
}
private
static
ByteMatrix generateMatrix
(
final
String data) {
QRCode qr =
new
QRCode
(
);
Encoder.encode
(
data, ErrorCorrectionLevel.L, qr);
ByteMatrix matrix =
qr.getMatrix
(
);
return
matrix;
}
...
De nouveau, quand j'ai ma matrice, je peux lancer la génération de l'image. Cette fois nous allons procéder par étapes.
public
class
ColoredQrcodeGenerator {
public
static
void
main
(
String[] args) {
...
ByteMatrix matrix =
generateMatrix
(
data);
int
size =
400
;
String imageFormat =
"png"
;
String outputFileName =
"c:/code/qrcode-01."
+
imageFormat;
// write in a file
writeImage
(
outputFileName, imageFormat, matrix, size);
}
private
static
void
writeImage
(
String outputFileName, String imageFormat, ByteMatrix matrix, final
int
size) {
...
}
...
La suite de ce chapitre n'est pas simple : elle utilise les fonctionnalités de Java 2D (qui nécessitent un peu de concentration), alors qu'on utilisait la génération automatisée (mais aux options réduites) de Zxing dans le chapitre précédent.
On commence par générer la « forme » du QR code (à l'aide de Java 2D) : modules, quietzone, etc.
public
class
ColoredQrcodeGenerator {
private
static
void
writeImage
(
String outputFileName, String imageFormat, ByteMatrix matrix, final
int
size) {
// Java 2D Traitement de Area
// Futurs modules
Area a =
new
Area
(
);
Area module
=
new
Area
(
new
Rectangle.Float
(
0
, 0
, 1
, 1
));
// Deplacement du module
AffineTransform at =
new
AffineTransform
(
);
int
width =
matrix.getWidth
(
);
for
(
int
i =
0
; i <
width; i++
) {
for
(
int
j =
0
; j <
width; j++
) {
if
(
matrix.get
(
j, i) ==
1
) {
// Ajout du module
a.add
(
module
);
}
// Decalage a droite
at.setToTranslation
(
1
, 0
);
module
.transform
(
at);
}
// Ligne suivante
at.setToTranslation
(-
width, 1
);
module
.transform
(
at);
}
// Agrandissement de l'Area pour le remplissage de l'image
double
ratio =
size /
(
double
) width;
// Quietzone : 4 modules de bordures autour du QR Code (zone vide pour bien identifier le code dans la page imprimee)
double
adjustment =
width /
(
double
) (
width +
8
);
ratio =
ratio *
adjustment;
at.setToTranslation
(
4
, 4
);
a.transform
(
at);
// On agrandit le tour a la taille souhaitee.
at.setToScale
(
ratio, ratio);
a.transform
(
at);
}
...
Puis on peut passer à l'étape de « coloriage » des modules ajoutés dans la boucle (cf. code source précédent).
public
class
ColoredQrcodeGenerator {
private
static
void
writeImage
(
String outputFileName, String imageFormat, ByteMatrix matrix, final
int
size) {
// Java 2D Traitement de Area
...
// Java 2D Traitement l'image
BufferedImage im =
new
BufferedImage
(
size, size, BufferedImage.TYPE_INT_RGB);
Graphics2D g =
(
Graphics2D) im.getGraphics
(
);
// Modules verts
Color vert =
new
Color
(
0xAFC828
);
g.setPaint
(
vert);
g.setBackground
(
new
Color
(
0xFFFFFF
));
// Fond blanc
g.clearRect
(
0
, 0
, size, size);
// Remplissage des modules
g.fill
(
a);
}
...
Enfin, on peut écrire le fichier sur le disque.
public
class
ColoredQrcodeGenerator {
private
static
void
writeImage
(
String outputFileName, String imageFormat, ByteMatrix matrix, final
int
size) {
// Java 2D Traitement de Area
...
// Java 2D Traitement l'image
...
// Ecriture sur le disque
File f =
new
File
(
outputFileName);
f.setWritable
(
true
);
ImageIO.write
(
im, imageFormat, f);
f.createNewFile
(
);
}
...
Ça me donne une belle image verte. Je vous laisse trouver la couleur qui vous convient le mieux…
III-D. un code avec redondance▲
Durée estimée : 30 secondes.
Une des particularités des QR codes est qu'ils restent lisibles même lorsqu'ils sont déchirés ou abîmés, un peu comme un CD qui reste utilisable lorsqu'il est rayé. Pour cela, la « norme » des QR codes implique que les données soient répliquées. Elle définit quatre niveaux de réplication : L (7 %), M (15 %), Q (25 %) et H (30 %).
Bien entendu, plus le niveau de réplication est élevé et plus gros devra être le QR code généré pour tout contenir.
Ici, une simple adaptation du code proposé au chapitre précédent devrait suffire.
public
class
LevelColoredQrcodeGenerator {
public
static
void
main
(
String[] args) {
String data =
"Je suis Thierry et je suis gentil."
;
ErrorCorrectionLevel level =
ErrorCorrectionLevel.Q;
// encode
ByteMatrix matrix =
generateMatrix
(
data, level);
...
}
private
static
ByteMatrix generateMatrix
(
String data, ErrorCorrectionLevel level) {
final
QRCode qr =
new
QRCode
(
);
Encoder.encode
(
data, level, qr);
final
ByteMatrix matrix =
qr.getMatrix
(
);
return
matrix;
}
...
Par défaut, Zxing génère des QR codes avec le niveau « L » (low). Dans l'exemple j'ai utilisé le niveau « Q » (quality) et on constate donc une plus grande densité des modules. Pour que ça saute aux yeux, j'ai utilisé du « bleu mauve » pour cette version.
Si on avait utilisé le niveau « H » (high), la différence aurait été encore plus flagrante.
III-E. Voir la grille▲
Durée estimée : 30 secondes.
Pour continuer, disons qu'on souhaite voir le maillage des modules. C'est relativement simple : il suffit de dessiner des modules qui n'occupent pas toute la place disponible dans la « case ».
public
class
GridQrcodeGenerator {
private
static
void
writeImage
(
String outputFileName, String imageFormat, ByteMatrix matrix, int
size) {
...
// Area module = new Area(new Rectangle.Float(0, 0, 1, 1));
Area module
=
new
Area
(
new
Rectangle2D.Float
(
0.05
f, 0.05
f, 0.9
f, 0.9
f));
...
}
...
III-F. Des modules ronds▲
Durée estimée : 30 secondes.
Continuons sur notre lancée. Cette fois, disons que nous voulons des modules ronds.
public
class
RoundedQrcodeGenerator {
private
static
void
writeImage
(
String outputFileName, String imageFormat, ByteMatrix matrix, int
size) {
...
//Area module = new Area(new Rectangle2D.Float(0.05f, 0.05f, 0.9f, 0.9f));
Area module
=
new
Area
(
new
RoundRectangle2D.Float
(
0
, 0
, 0.9
f, 0.9
f, 1
f, 1
f));
...
}
...
Juste pour rigoler, j'ai fait des modules ronds et blancs sur fond bleu. On a aussi le droit de changer la couleur du fond puisque c'est la différence de contraste qui compte. Toutefois tous les scanners ne savent pas forcément lire les QR codes inversés.
Avec le fond bleu, on voit bien la « quietzone » de quatre modules autour du QR code.
III-G. Avec un dégradé de couleur▲
Durée estimée : 30 secondes.
Pour finir avec un dernier effet sympa et simple, je vous propose d'utiliser un dégradé de couleur.
public
class
TransColoredQrcodeGenerator {
private
static
void
writeImage
(
String outputFileName, String imageFormat, ByteMatrix matrix, int
size) {
...
// Color couleur1 = new Color(0xFFFFFF);
// g.setPaint(couleur1);
Color couleur1 =
new
Color
(
0xAFC828
);
Color couleur2 =
new
Color
(
0x606640
);
// Debut et fin du gradient
float
[] fractions =
{
0.0
f, 1.0
f }
;
Color[] colors =
{
couleur1, couleur2 }
;
g.setPaint
(
new
RadialGradientPaint
(
size /
2
, size /
2
, size /
2
, fractions, colors));
...
}
...
III-H. Autres types de messages▲
La plupart du temps, on va générer des QR codes pour les faire « pointer » vers des sites Web. Pour cela, il suffit d'encoder un message contenant l'URL du-dit site.
public
static
void
main
(
String[] args) {
// String data = "Je suis Thierry et je suis gentil.";
String data =
"http://www.developpez.com"
;
...
Pour générer des QR codes permettant d'envoyer des SMS, des e-mails, d'appeler un numéro de téléphone, d'enregistrer des vCards (etc.), il y a une syntaxe particulière que je vous laisse découvrir sur le site d'UnitagUnitag ou sur la page dédiée aux contenus chez Zxing. Voici néanmoins quelques exemples simples :
public
static
void
main
(
String[] args) {
// String data = "Je suis Thierry et je suis gentil.";
// String data = "http://www.developpez.com";
// Envoie de SMS
String data =
"sms:+33312345678:bonjour..."
;
// Envoie d'email
String data =
"mail:jean.dupond@google.com?subject=Coucou&body=Bonjour..."
;
...
III-I. Réduction d'adresse▲
Il y a un point auquel on ne pense jamais, c'est de réduire la taille du message contenu dans le QR code. En effet, plus le message est long et plus il faudra de modules pour le représenter. Sur une surface d'impression donnée, cela se traduit par des modules plus petits et donc plus difficiles à scanner.
C'est difficile lorsqu'il s'agit d'une phrase, car on ne va pas enlever des mots. Par contre il existe des techniques pour les URL. Mais avant ça, partons d'un constat. Il faut 95 caractères pour représenter l'adresse de cet article en ligne : https://thierry-leriche-dessirier.developpez.com/tutoriels/java/creer-qrcode-zxing-java2d-5-min/
En utilisant les programmes présentés ci-dessus, cela nous donne le QR code orange suivant :
Plusieurs sites, dont bit.ly, proposent des services de réduction de la taille des adresses. Cela permet d'arriver sur cet article grâce à l'URL http://bit.ly/V2AtCZ qui ne comporte que 19 caractères. Le gain est incontestable.
Cette seconde URL nous permet de créer le QR code rose suivant :
En mettant les deux QR codes à côté, on devine que le second sera bien plus facile à scanner.
Et voilà…
IV. Conclusions▲
Comme on vient de le voir, on peut générer des QR codes très facilement à l'aide de la bibliothèque Zxing et un peu de dessin à l'aide de Java 2D. Les possibilités sont nombreuses, mais réclament un talent de graphiste qui me manque. Vous trouverez des outils sympas sur le Web et j'espère qu'ils vous donneront des idées.
Dans un prochain article, je m'attarderai sur les algorithmes liés aux QR codes, notamment pour le calcul de la matrice, des masques, des mécanismes de correction d'erreur, etc. Mais pour le moment, je vous laisse déjà vous amuser avec tout ça.
Le code final de ce tutoriel est disponible dans le fichier ZIP qr-code-02.zip.code final
Vos retours nous aident à améliorer nos publications. N'hésitez donc pas à commenter cet article sur le forum : 34 commentaires
Retrouvez mes autres tutoriels rapides sur developpez.com à l'adresse https://thierry-leriche-dessirier.developpez.com/#page_articlesTutoriels
V. Remerciements▲
J'adresse des remerciements particuliers aux équipes d'Unitag, sans qui cet article n'aurait jamais vu le jour. Unitag est une société française, basée à Toulouse et leader dans le domaine de la génération et la personnalisation des QR Codes. Leur site Web propose de nombreux outils gratuits (et performants) que viennent compléter des offres professionnelles intéressantes (et pas chères).
Et en plus, je tiens à remercier, en tant qu'auteur du tutoriel, toutes les personnes qui m'ont aidé et soutenu. Je pense tout d'abord à mes collègues qui subissent mes questions au quotidien, mais aussi à mes contacts et amis du Web, dans le domaine de l'informatique ou non, qui m'ont fait part de leurs remarques et critiques. Bien entendu, je n'oublie pas l'équipe de developpez.com qui m'a guidé dans la rédaction de cet article et m'a aidé à le corriger et le faire évoluer, principalement sur le forum.
Plus particulièrement j'adresse mes remerciements à Mickael Baron (keulkeul), Sébastien Germez (FirePrawn), Marc (Gueritarish) et mlny84.
VI. Annexes▲
VI-A. Des exemples de beaux QR codes▲
Voici une petite sélection de QR codes design que j'ai simplement cherché sur Google.. Je les trouve beaux, mais ça n'engage que moi.
Quand on scanne des QR codes (à l'aide d'un iPhone par exemple) directement sur l'écran et de trop près, on voit apparaitre des lignes correspondant à la matrice des pixels du LCD. Il est donc possible que ces QR codes ne soient pas lisibles sur tous les écrans. En revanche ils devraient être lisibles facilement une fois imprimés, même sur des mauvaises imprimantes, même en noir et blanc.
Ces images sont la propriété de leurs auteurs. Je les propose ici dans le cadre du « fair use ». Contactez-moi pour les supprimer ou ajouter des références.
VI-B. Liens▲
Unitag : http://www.unitag.fr
QR Dress Code : http://www.qrdresscode.com
Zxing : http://code.google.com/p/zxing/
Je vous conseille aussi la lecture du très bon article de Eric POMMEREAU, intitulé « Usages des codes à barres 2D, QR Codes et flashcodes », dans lequel il explique les différents usages intéressants.
https://eric-pommereau.developpez.com/tutoriels/general/usages-codes-barres-2d/
VI-C. Liens personnels▲
Retrouvez ma page et mes autres articles sur developpez.com à l'adresse https://thierry-leriche-dessirier.developpez.com/#page_articlesTutoriels
Ajoutez-moi à vos contacts à l'aide du QR Code suivant :
Suivez-moi sur Twitter : @thierryleriche@thierryleriche
VI-D. Les fichiers importants en entier▲
package
com.dvp.tutoriel.qrcode;
import
java.io.File;
import
java.io.FileNotFoundException;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
com.google.zxing.BarcodeFormat;
import
com.google.zxing.WriterException;
import
com.google.zxing.client.j2se.MatrixToImageWriter;
import
com.google.zxing.common.BitMatrix;
import
com.google.zxing.qrcode.QRCodeWriter;
public
class
SimpleQrcodeGenerator {
private
static
BitMatrix generateMatrix
(
final
String data, final
int
size) throws
WriterException {
final
BitMatrix bitMatrix =
new
QRCodeWriter
(
).encode
(
data, BarcodeFormat.QR_CODE, size, size);
return
bitMatrix;
}
private
static
void
writeImage
(
final
String outputFileName, final
String imageFormat, final
BitMatrix bitMatrix) throws
FileNotFoundException,
IOException {
final
FileOutputStream fileOutputStream =
new
FileOutputStream
(
new
File
(
outputFileName));
MatrixToImageWriter.writeToStream
(
bitMatrix, imageFormat, fileOutputStream);
fileOutputStream.close
(
);
}
/**
*
@param
args
*/
public
static
void
main
(
String[] args) {
System.out.println
(
"SimpleQrcodeGenerator DEBUT"
);
try
{
final
String data =
"Je suis Thierry et je suis gentil."
;
final
String imageFormat =
"png"
;
final
String outputFileName =
"c:/code/qrcode-01."
+
imageFormat;
final
int
size =
400
;
// encode
final
BitMatrix bitMatrix =
generateMatrix
(
data, size);
// write in a file
writeImage
(
outputFileName, imageFormat, bitMatrix);
System.out.println
(
"SimpleQrcodeGenerator FIN"
);
}
catch
(
Exception e) {
e.printStackTrace
(
);
}
}
}
package
com.dvp.tutoriel.qrcode;
import
java.awt.Color;
import
java.awt.Graphics2D;
import
java.awt.geom.AffineTransform;
import
java.awt.geom.Area;
import
java.awt.geom.Rectangle2D;
import
java.awt.image.BufferedImage;
import
java.io.File;
import
java.io.FileNotFoundException;
import
java.io.IOException;
import
javax.imageio.ImageIO;
import
com.google.zxing.WriterException;
import
com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import
com.google.zxing.qrcode.encoder.ByteMatrix;
import
com.google.zxing.qrcode.encoder.Encoder;
import
com.google.zxing.qrcode.encoder.QRCode;
public
class
GridQrcodeGenerator {
private
static
ByteMatrix generateMatrix
(
final
String data, final
ErrorCorrectionLevel level) throws
WriterException {
final
QRCode qr =
new
QRCode
(
);
Encoder.encode
(
data, level, qr);
final
ByteMatrix matrix =
qr.getMatrix
(
);
return
matrix;
}
private
static
void
writeImage
(
final
String outputFileName, final
String imageFormat, final
ByteMatrix matrix, final
int
size)
throws
FileNotFoundException, IOException {
/**
* Java 2D Traitement de Area
*/
Area a =
new
Area
(
); // les futurs modules
Area module
=
new
Area
(
new
Rectangle2D.Float
(
0.05
f, 0.05
f, 0.9
f, 0.9
f));
AffineTransform at =
new
AffineTransform
(
); // pour déplacer le module
int
width =
matrix.getWidth
(
);
for
(
int
i =
0
; i <
width; i++
) {
for
(
int
j =
0
; j <
width; j++
) {
if
(
matrix.get
(
j, i) ==
1
) {
a.add
(
module
); // on ajoute le module
}
at.setToTranslation
(
1
, 0
); // on décale vers la droite
module
.transform
(
at);
}
at.setToTranslation
(-
width, 1
); // on saute une ligne on revient au
// début
module
.transform
(
at);
}
// agrandissement de l'Area pour le remplissage de l'image
double
ratio =
size /
(
double
) width;
// il faut respecter la Quietzone : 4 modules de bordures autour du QR
// Code
double
adjustment =
width /
(
double
) (
width +
8
);
ratio =
ratio *
adjustment;
at.setToTranslation
(
4
, 4
); // à cause de la quietzone
a.transform
(
at);
at.setToScale
(
ratio, ratio); // on agrandit
a.transform
(
at);
/**
* Java 2D Traitement l'image
*/
BufferedImage im =
new
BufferedImage
(
size, size, BufferedImage.TYPE_INT_RGB);
Graphics2D g =
(
Graphics2D) im.getGraphics
(
);
Color couleur1 =
new
Color
(
0xFF0000
);
g.setPaint
(
couleur1);
g.setBackground
(
new
Color
(
0xFFFFFF
));
g.clearRect
(
0
, 0
, size, size); // pour le fond blanc
g.fill
(
a); // remplissage des modules
// Ecriture sur le disque
File f =
new
File
(
outputFileName);
f.setWritable
(
true
);
try
{
ImageIO.write
(
im, imageFormat, f);
f.createNewFile
(
);
}
catch
(
Exception e) {
}
}
/**
*
@param
args
*/
public
static
void
main
(
String[] args) {
System.out.println
(
"GridQrcodeGenerator DEBUT"
);
try
{
final
String data =
"Je suis Thierry et je suis gentil."
;
final
String imageFormat =
"png"
;
final
String outputFileName =
"c:/code/qrcode-04."
+
imageFormat;
final
int
size =
400
;
final
ErrorCorrectionLevel level =
ErrorCorrectionLevel.Q;
// encode
final
ByteMatrix matrix =
generateMatrix
(
data, level);
// write in a file
writeImage
(
outputFileName, imageFormat, matrix, size);
System.out.println
(
"GridQrcodeGenerator FIN"
);
}
catch
(
Exception e) {
e.printStackTrace
(
);
}
}
}
<project
xmlns
=
"http://maven.apache.org/POM/4.0.0"
xmlns
:
xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi
:
schemaLocation
=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0</modelVersion>
<groupId>
com.tle.qrcodegen</groupId>
<artifactId>
qrcode-generator</artifactId>
<version>
1.0-SNAPSHOT</version>
<packaging>
jar</packaging>
<name>
qrcode-generator</name>
<description>
TODO</description>
<url>
http://www.icauda.com</url>
<licenses>
<license>
<name>
Copyright ©1995-2012 icauda.com et Copyright ©2011 Developpez.com</name>
<comments>
Les sources présentés sur cette page sont libres de droits, et vous pouvez les utiliser à votre [..]</comments>
</license>
</licenses>
<developers>
<!-- Thierry -->
<developer>
<name>
Thierry Leriche-Dessirier</name>
<roles>
<role>
Developper</role>
</roles>
<organization>
ICAUDA</organization>
</developer>
</developers>
<properties>
<project.build.sourceEncoding>
UTF-8</project.build.sourceEncoding>
<java.version>
1.6</java.version>
<maven-compiler-plugin.version>
2.3.1</maven-compiler-plugin.version>
<junit.version>
4.8.2</junit.version>
<log4j.version>
1.2.13</log4j.version>
<guava.version>
12.0</guava.version>
<zxing-core.version>
2.0</zxing-core.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- JUnit -->
<dependency>
<groupId>
junit</groupId>
<artifactId>
junit</artifactId>
<version>
${junit.version}</version>
<scope>
test</scope>
</dependency>
<!-- log4j -->
<dependency>
<groupId>
log4j</groupId>
<artifactId>
log4j</artifactId>
<version>
${log4j.version}</version>
</dependency>
<!-- Guava -->
<dependency>
<groupId>
com.google.guava</groupId>
<artifactId>
guava</artifactId>
<version>
${guava.version}</version>
</dependency>
<!-- zxing -->
<dependency>
<groupId>
com.google.zxing</groupId>
<artifactId>
core</artifactId>
<version>
${zxing-core.version}</version>
</dependency>
<dependency>
<groupId>
com.google.zxing</groupId>
<artifactId>
javase</artifactId>
<version>
${zxing-core.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>
junit</groupId>
<artifactId>
junit</artifactId>
<scope>
test</scope>
</dependency>
<!-- Guava -->
<dependency>
<groupId>
com.google.guava</groupId>
<artifactId>
guava</artifactId>
</dependency>
<!-- zxing -->
<dependency>
<groupId>
com.google.zxing</groupId>
<artifactId>
core</artifactId>
</dependency>
<dependency>
<groupId>
com.google.zxing</groupId>
<artifactId>
javase</artifactId>
</dependency>
</dependencies>
<build>
<finalName>
qrcode-generator</finalName>
<plugins>
<plugin>
<artifactId>
maven-compiler-plugin</artifactId>
<version>
${maven-compiler-plugin.version}</version>
<configuration>
<source>
${java.version}</source>
<target>
${java.version}</target>
<encoding>
${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>