美文网首页
使用zxing生成二维码去除白边

使用zxing生成二维码去除白边

作者: 小石读史 | 来源:发表于2020-09-29 11:56 被阅读0次

    生成二维码的时候,我们通常使用google.zxing包,使用google提供的工具类生成二维码的时候通常会带有白色边框,有的人觉得白色的边框很难看,那么怎么去除白色的边框呢?
    我们先把zxing的源码下载下来。然后看下这个白边是如果产生的。

    首先是创建比特矩阵(位矩阵)的QR码编码的字符串的代码:

    new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, hintMap);
    

    encode方法源码如下:

    public BitMatrix encode(String contents,
                              BarcodeFormat format,
                              int width,
                              int height,
                              Map<EncodeHintType,?> hints) throws WriterException {
    
        if (contents.isEmpty()) {
          throw new IllegalArgumentException("Found empty contents");
        }
    
        if (format != BarcodeFormat.QR_CODE) {
          throw new IllegalArgumentException("Can only encode QR_CODE, but got " + format);
        }
    
        if (width < 0 || height < 0) {
          throw new IllegalArgumentException("Requested dimensions are too small: " + width + 'x' +
              height);
        }
    
        ErrorCorrectionLevel errorCorrectionLevel = ErrorCorrectionLevel.L;
        int quietZone = QUIET_ZONE_SIZE;
        if (hints != null) {
          ErrorCorrectionLevel requestedECLevel = (ErrorCorrectionLevel) hints.get(EncodeHintType.ERROR_CORRECTION);
          if (requestedECLevel != null) {
            errorCorrectionLevel = requestedECLevel;
          }
          Integer quietZoneInt = (Integer) hints.get(EncodeHintType.MARGIN);
          if (quietZoneInt != null) {
            quietZone = quietZoneInt;
          }
        }
    
        QRCode code = Encoder.encode(contents, errorCorrectionLevel, hints);
        return renderResult(code, width, height, quietZone);
      }
    

    在方法的最后两行我们看到调用renderResult方法,源码如下

    private static BitMatrix renderResult(QRCode code, int width, int height, int quietZone) {
        ByteMatrix input = code.getMatrix();
        if (input == null) {
          throw new IllegalStateException();
        }
        int inputWidth = input.getWidth();
        int inputHeight = input.getHeight();
        //以下两行源码是原始代码中控制边距的参数
        //int qrWidth = inputWidth + (quietZone << 1);
        //int qrHeight = inputHeight + (quietZone << 1);
       //以下两行源码是修改后的控制边距的参数
        int qrWidth = inputWidth + 2;
        int qrHeight = inputHeight + 2;
        int outputWidth = Math.max(width, qrWidth);
        int outputHeight = Math.max(height, qrHeight);
    
        int multiple = Math.min(outputWidth / qrWidth, outputHeight / qrHeight);
        // Padding includes both the quiet zone and the extra white pixels to accommodate the requested
        // dimensions. For example, if input is 25x25 the QR will be 33x33 including the quiet zone.
        // If the requested size is 200x160, the multiple will be 4, for a QR of 132x132. These will
        // handle all the padding from 100x100 (the actual QR) up to 200x160.
        int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;
        int topPadding = (outputHeight - (inputHeight * multiple)) / 2;
    
        BitMatrix output = new BitMatrix(outputWidth, outputHeight);
    
        for (int inputY = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple) {
          // Write the contents of this row of the barcode
          for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {
            if (input.get(inputX, inputY) == 1) {
              output.setRegion(outputX, outputY, multiple, multiple);
            }
          }
        }
    
        return output;
      }
    

    修改代码位置如下,具体想要使用多大的间距可以自行调整qrWidth 以及qrHeight :


    image.png

    测试类:

    /**
     * 二维码生成和读的工具类
     */
    public class QRCodeUtil {
    
        /**
         * 生成包含字符串信息的二维码图片
         *
         * @param outputStream 文件输出流路径
         * @param content      二维码携带信息
         * @param qrCodeSize   二维码图片大小
         * @param imageFormat  二维码的格式
         * @throws WriterException
         * @throws IOException
         */
        public static boolean createQrCode(OutputStream outputStream, String content, int qrCodeSize, String imageFormat) throws WriterException, IOException {
            //设置二维码纠错级别MAP
            Hashtable<EncodeHintType, ErrorCorrectionLevel> hintMap = new Hashtable<EncodeHintType, ErrorCorrectionLevel>();
            hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);  // 矫错级别
            QRCodeWriterUtil qrCodeWriterUtil = new QRCodeWriterUtil();
            //创建比特矩阵(位矩阵)的QR码编码的字符串
            BitMatrix byteMatrix = qrCodeWriterUtil.encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, hintMap);
            // 使BufferedImage勾画QRCode  (matrixWidth 是行二维码像素点)
            int matrixWidth = byteMatrix.getWidth();
            BufferedImage image = new BufferedImage(matrixWidth - 20, matrixWidth - 20, BufferedImage.TYPE_INT_RGB);
            image.createGraphics();
            Graphics2D graphics = (Graphics2D) image.getGraphics();
            graphics.setColor(Color.WHITE);
            graphics.fillRect(0, 0, matrixWidth, matrixWidth);
            // 使用比特矩阵画并保存图像
            graphics.setColor(Color.BLACK);
            for (int i = 0; i < matrixWidth; i++) {
                for (int j = 0; j < matrixWidth; j++) {
                    if (byteMatrix.get(i, j)) {
                        graphics.fillRect(i - 10, j - 10, 1, 1);
                    }
                }
            }
    
            return ImageIO.write(image, imageFormat, outputStream);
        }
    
        /**
         * 读二维码并输出携带的信息
         */
        public static void readQrCode(InputStream inputStream) throws IOException {
            //从输入流中获取字符串信息
            BufferedImage image = ImageIO.read(inputStream);
            //将图像转换为二进制位图源
            LuminanceSource source = new BufferedImageLuminanceSource(image);
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
            QRCodeReader reader = new QRCodeReader();
            Result result = null;
            try {
                result = reader.decode(bitmap);
            } catch (ReaderException e) {
                e.printStackTrace();
            }
            System.out.println(result.getText());
        }
    
        /**
         * 测试代码
         *
         * @throws Exception
         */
        public static void main(String[] args) throws Exception {
            String fileName = "F:\\tmp" + StringUtils.generateUUID() + ".jpg";
            File workFile = new File(fileName);
            createQrCode(new FileOutputStream(workFile), "https://www.baidu.com", 500, "JPEG");
    
            readQrCode(new FileInputStream(ResourceUtils.getFile(fileName)));
        }
    
    }
    

    测试结果:

    相关文章

      网友评论

          本文标题:使用zxing生成二维码去除白边

          本文链接:https://www.haomeiwen.com/subject/vifeuktx.html