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:
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 Writer
encode(...)
, 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.
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.
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>
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)