La methode facile de créer des QR codes avec Zxing et Java 2D

La methode facile de créer des QR codes avec Zxing et Java 2D


I. Introduction

Un QR code est la représentation graphique d’un message. C’est une sorte de code barre en deux dimensions. Le-dit 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.


QR code vers le site de Developpez.com
QR code vers le site de Developpez.com
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.


info 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.


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.


idea 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”.
Dépendance dans le 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.
Commande 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 :
Commande Maven

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” correspondants aux modules noirs et blancs.
Calcul de la matrice

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.
Dessin

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();
}

...
info 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”.


QR code : Je suis Thierry et je suis gentil.
Voici ce que ça donne lorsque je scanne ce code depuis mon iPhone :


Scan en cours sur l'iPhone
Scan en cours sur l’iPhone
Après le scan
Après le scan


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.
Calcul de la matrice

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.
Dessin

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) {
...
}

...
warning 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érér la “forme” du QR code (à l’aide de Java 2D) : modules, quietzone, etc.
Area

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).
Dessin

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.
Ecriture 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();
}

...
Ca me donne une belle image verte. Je vous laisse trouver la couleur qui vous convient le mieux…


QR code vert
QR code vert


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 %).


idea 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.
Calcul de la matrice

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.


QR code vert avec le niveau L
QR code vert avec le niveau L
QR code bleu mauve avec le niveau Q
QR code bleu mauve avec le niveau Q
idea 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”.
Modules plus petits laissant voir la grille

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.05f, 0.05f, 0.9f, 0.9f));

...
}

...
QR code bleu mauve
QR code bleu mauve
QR code rouge avec grille
QR code rouge avec grille


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.
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.9f, 0.9f, 1f, 1f));

...
}

...
Juste pour rigoler, j’ai fais 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.


QR code rouge avec grille
QR code rouge avec grille
QR code avec des modules ronds
QR code avec des modules ronds
idea 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.
Dégradé de couleurs

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.0f, 1.0f };
Color[] colors = { couleur1, couleur2 };
g.setPaint(new RadialGradientPaint(size / 2, size / 2, size / 2, fractions, colors));

...
}

...
QR code avec un dégradé de couleurs
QR code avec un dégradé de couleurs


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 de d’encoder un message contenant l’URL du-dit site.
Dégradé de couleurs

public static void main(String[] args) {
// String data = "Je suis Thierry et je suis gentil.";
String data = "http://www.developpez.com";

...
QR code vers le site www.developpez.com
QR code vers le site 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’Unitag ou sur la page dédiée aux contenus chez Zxing. Voici néanmoins quelques exemples simples :
Dégradé de couleurs

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...";

...
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.


idea Vos retours nous aident à améliorer nos publications. N’hésitez donc pas à commenter cet article sur le forum : 1 commentaire Donner une note à l'article (5)
Retrouvez mes autres tutoriels rapides sur developpez.com à l’adresse http://thierry-leriche-dessirier.developpez.com/#page_articles



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 la 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.


idea 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.
warning 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


QR Code vers Unitag
QR Code vers Unitag
QR Code design vers Unitag
QR Code design vers Unitag


QR Code vers QR Dress Code



VI-C. Liens personnels

Retrouvez ma page et mes autres articles sur developpez.com à l’adresse http://thierry-leriche-dessirier.developpez.com/#page_articles


QR Code vers mes articles
Ajoutez-moi à vos contacts à l’aide du QR Code suivant :


QR Code contenant ma vCard
Suivez-moi sur Twitter : @thierryleriche


@thierryleriche
@thierryleriche


VI-D. Les fichiers importants en entier

SimpleQrcodeGenerator.java

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();
}
}
}
GridQrcodeGenerator.java

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.05f, 0.05f, 0.9f, 0.9f));

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();
}
}
}
pom.xml

<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>


               Version PDF   Version hors-ligne   Version eBooks


Leave a comment