Reduce border width on QR Codes generated by ZXing?

后端 未结 4 611
傲寒
傲寒 2021-01-30 20:58

I\'m using com.google.zxing.qrcode.QRCodeWriter to encode data and com.google.zxing.client.j2se.MatrixToImageWriter to generate the QR Code image. On a

相关标签:
4条回答
  • 2021-01-30 21:08

    Even by setting EncodeHintType.MARGIN to 0, the algorithm that convert the QRCode "dot" matrix to pixels data can generate a small margin (the algorithm enforce a constant number of pixels per dots, so the margin pixel size is the remainder of the integer division of pixels size by QR-Code dot size).

    However you can completely bypass this "dot to pixel" generation: you compute the QRCode dot matrix directly by calling the public com.google.zxing.qrcode.encoder.Encoder class, and generate the pixel image yourself. Code below:

    // 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);
    

    The conversion of the BufferedImage to PNG data is left as an exercise to the reader. You can also scale the image by setting a fixed number of pixels per dots.

    It's usually more optimized that way, the generated image size is the smallest possible. If you rely on client to scale the image (w/o blur) you do not need more than 1 pixel per dot.

    0 讨论(0)
  • 2021-01-30 21:09

    The QR spec requires a four module quiet zone and that's what zxing creates. (See QUIET_ZONE_SIZE in QRCodeWriter.renderResult.)

    More recent versions of ZXing allow you to set the size of the quiet zone (basically the intrinsic padding of the QR code) by supplying an int value with the EncodeHintType.MARGIN key. Simply include it in the hints Map you supply to the Writer's encode(...) method, e.g.:

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

    If you change this, you risk lowering the decode success rate.

    0 讨论(0)
  • 2021-01-30 21:25
        HashMap hintMap = new HashMap();
        hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
        hintMap.put(EncodeHintType.MARGIN, -1);
    

    no margin

    UPDATE

    Add dependencies (from comments)

    <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>
    
    0 讨论(0)
  • 2021-01-30 21:35

    In swift you can:

    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)
    
    0 讨论(0)
提交回复
热议问题