web-dev-qa-db-fra.com

Réduire la largeur de la bordure sur les codes QR générés par ZXing?

J'utilise com.google.zxing.qrcode.QRCodeWriter pour encoder les données et com.google.zxing.client.j2se.MatrixToImageWriter pour générer l'image QR Code. Sur une image 400x400, il y a environ une bordure de 52 pixels de large autour du code. J'aimerais que cette bordure soit plus étroite, peut-être 15 pixels, mais je ne vois rien dans l'API pour le faire. Suis-je en train de manquer quelque chose dans la documentation? Ou aurais-je besoin de traiter l'image moi-même?

Pour référence, voici un exemple de code QR 400x400 produit avec la bibliothèque ZXing:

An example QR Code

34
James Sumners

La spécification QR nécessite une zone silencieuse à quatre modules et c'est ce que zxing crée . (Voir QUIET_ZONE_SIZE Dans QRCodeWriter.renderResult .)

Des versions plus récentes de ZXing vous permettent de définir la taille de la zone silencieuse (essentiellement le remplissage intrinsèque du code QR) en fournissant une valeur int avec la touche EncodeHintType.MARGIN . Incluez-le simplement dans les conseils Map que vous fournissez à la méthode Writerencode(...) , par exemple:

Map<EncodeHintType, Object> hints = new EnumMap<EncodeHintType, Object>(EncodeHintType.class);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.MARGIN, 2); /* default = 4 */

Si vous changez cela, vous risquez de réduire le taux de réussite du décodage.

69
smparkes

Même en définissant EncodeHintType.MARGIN à 0, l'algorithme qui convertit la matrice de "points" QRCode en données de pixels peut générer une petite marge (l'algorithme applique un nombre constant de pixels par points, donc la taille des pixels de marge est le reste de la division entière de la taille des pixels par QR -Taille du point de code).

Cependant, vous pouvez complètement contourner cette génération "point à pixel": vous calculez la matrice de points QRCode directement en appelant le public com.google.zxing.qrcode.encoder.Encoder classe, et générez vous-même l'image pixel. Code ci-dessous:

// Step 1 - generate the QRCode dot array
Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>(1);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
QRCode qrCode = Encoder.encode(what, ErrorCorrectionLevel.L, hints);

// Step 2 - create a BufferedImage out of this array
int width = qrCode.getMatrix().getWidth();
int height = qrCode.getMatrix().getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int[] rgbArray = new int[width * height];
int i = 0;
for (int y = 0; y < height; y++) {
  for (int x = 0; x < width; x++) {
    rgbArray[i] = qrCode.getMatrix().get(x, y) > 0 ? 0xFFFFFF : 0x000000;
    i++;
} }
image.setRGB(0, 0, width, height, rgbArray, 0, width);

La conversion des BufferedImage en données PNG est laissée au lecteur comme exercice. Vous pouvez également mettre à l'échelle l'image en définissant un nombre fixe de pixels par points.

C'est généralement plus optimisé de cette façon, la taille de l'image générée est la plus petite possible. Si vous comptez sur le client pour redimensionner l'image (sans flou), vous n'avez pas besoin de plus de 1 pixel par point.

9
Laurent Grégoire
    HashMap hintMap = new HashMap();
    hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
    hintMap.put(EncodeHintType.MARGIN, -1);

pas de marge

MISE À JOUR

Ajouter des dépendances (à partir des commentaires)

<dependency>
    <groupId>com.google.zxing</groupId> 
    <artifactId>core</artifactId> 
    <version>3.2.0</version>
    <type>jar</type> 
</dependency> 
<dependency> 
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId> 
    <version>3.2.0</version> 
</dependency>
1
ougalejo

Dans Swift vous pouvez:

let hints = ZXEncodeHints()
hints!.margin = NSNumber(int: 0)

let result = try writer.encode(code, format: format, width: Int32(size.width), height: Int32(size.height), hints: hints)
let cgImage = ZXImage(matrix: result, onColor: UIColor.blackColor().CGColor, offColor: UIColor.clearColor().CGColor).cgimage
let QRImage = UIImage(CGImage: cgImage)
1
Luca Davanzo