zoukankan      html  css  js  c++  java
  • java学习-zxing生成二维码矩阵的简单例子

    这个例子需要使用google的开源项目zxing的核心jar包

    core-3.2.0.jar

    可以百度搜索下载jar文件,也可使用maven添加依赖

            <dependency>
                <groupId>com.google.zxing</groupId>
                <artifactId>core</artifactId>
                <version>3.2.0</version>
            </dependency>

    下面是将生成的二维码矩阵写入到jpg文件中。

         * 生成二维码图片
         * @param dir        存放的目录
         * @param fileName  文件名要以.jpg结尾
         * @param content  这个内容可以是文字或链接
         */
        public static void generateQRCode(String dir, String fileName, String content) {
            //生成二维码的宽高
            int size = 400;
            Map<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
            // 指定纠错等级
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
            // 指定编码格式
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            // 指定二维码的边距,设置后无效,,设置纠错等级ErrorCorrectionLevel.H为高等级时,无效
    //hints.put(EncodeHintType.MARGIN, 1);
            try {
                //encode(String contents, BarcodeFormat format, int width, int height, Map<EncodeHintType, ?> hints)
                BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, size, size, hints);
    
                //bitMatrix = updateBit(bitMatrix, 20);
                File file1 = new File(dir);
                if (!file1.exists()) {
                    file1.mkdirs();
                }
    
                //将生成的矩阵像素写入到指定文件中,这里是以jpg结尾
                MatrixToImageWriter.writeToStream(bitMatrix, "jpg", new FileOutputStream(dir + "/" + fileName));
                System.out.println("创建成功");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (WriterException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    上面指定了纠错等级设置有四个值

     /** L = ~7% correction */
      L(0x01),
      /** M = ~15% correction */
      M(0x00),
      /** Q = ~25% correction */
      Q(0x03),
      /** H = ~30% correction */
      H(0x02);

    指定为L,M 这两个等级时,二维码大小会根据其存储的数据量变化,即边距肯能会很大,看下图,

    Q,H高等级时,会按照标准格式显示二维码图片。建议使用H等级。

    这里生成的二维码留的白色边距有点多,想要适当减小边距,看下图

    如果不想边距太大,我们可以将生成的二维码图片进行剪切。新建立一个空的BitMatrix对象来放这个二维码

    margin为白色边距的大小

    private static BitMatrix updateBit(BitMatrix matrix, int margin) {
    
            int tempM = margin * 2;
    
            //left,top,width,height 
            // 0    1    2     3   对应的数组下标
            //这里的width和height是指去除白色边框后的真实的二维码长宽,而不是图片长宽。
            int[] rec = matrix.getEnclosingRectangle(); // 获取二维码图案的属性
    
            int resWidth = rec[2] + tempM;//真实宽度加左右边距
            int resHeight = rec[3] + tempM;
    
            BitMatrix resMatrix = new BitMatrix(resWidth, resHeight); // 按照自定义边框生成新的BitMatrix
    
            resMatrix.clear();
            //从上->下按列进行值得复制,即一列一列的扫描到新的二维矩阵中
            for (int i = margin; i < resWidth - margin; i++) { // 循环,将二维码图案绘制到新的bitMatrix中
    
                for (int j = margin; j < resHeight - margin; j++) {
                    //margin + rec[0]
                    if (matrix.get(i - margin + rec[0], j - margin + rec[1])) {
    
                        resMatrix.set(i, j);
    
                    }
    
                }
    
            }
    
            return resMatrix;
        }

    生成二维码

    这样白色边距就不会太大了,好看多了

    后面还有将二维码嵌入到海报,或者其他活动图片上的方法,直接上代码

    将二维码放置在图片右下角的位置

    public void insertQRCode(BufferedImage zxingImage, String backgroundPath) {
            InputStream dest = null;
    
            try {
                dest = new FileInputStream(backgroundPath);
                BufferedImage image = ImageIO.read(dest);
    
                Graphics g = image.getGraphics();
    
                int leftMargin = image.getWidth() - zxingImage.getWidth() - 10;
                int topMargin = image.getHeight() - zxingImage.getHeight() - 10;
                g.drawImage(zxingImage, leftMargin, topMargin, zxingImage.getWidth(), zxingImage.getHeight(), null);
                ImageIO.write(image, "jpg", new FileOutputStream("D:\QRCode\zengmei.jpg"));
                System.out.println("创建成功");
                
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

     生成后的结果,图片是本地随便找了一张图片

    修改二维码线条颜色,在二维码中插入logo图标等方法

    发现修改二维码颜色之后,用微信,qq扫描二维码很难被识别。这个很难受。这里说下怎么改。

    修改原理就是,将内容通过new MultiFormatWriter().encode()方法生成二维矩阵后,,

    用一个新的BufferedImage对象作为容器给矩阵的两个不同的值设置颜色,有值得为true,没值false,即设置黑白两种颜色

    /**
         * 
         * @param onColor 二维码的颜色,即黑白二维码的黑色 :0xFF000000  蓝色 0xFF000055
         * @param offColor 二维码的背景色   如白色:0xFFFFFFFF
         */
        public static void generateOtherQRCode(int onColor, int offColor) {
            String content = "小姐姐最棒啦^_^";
            int size = 200;
            Map<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
            // 指定纠错等级
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
            // 指定编码格式
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            try {
                BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, size, size, hints);
                BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix,
                        new MatrixToImageConfig(onColor, offColor));
    
                ImageIO.write(image, "png", new FileOutputStream("D:/QRCode/beautiful.png"));
                System.out.println("操作成功");
                
            } catch (IOException e) {
                e.printStackTrace();
            } catch (WriterException e) {
                e.printStackTrace();
            }
        }

    重要方法是:MatrixToImageWriter.toBufferedImage
    也就是设置颜色,然后返回BufferImage对象
    public static BufferedImage toBufferedImage(BitMatrix matrix, MatrixToImageConfig config) {
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, config.getBufferedImageColorModel());
        int onColor = config.getPixelOnColor();
        int offColor = config.getPixelOffColor();
        for (int x = 0; x < width; x++) {
          for (int y = 0; y < height; y++) {
            image.setRGB(x, y, matrix.get(x, y) ? onColor : offColor);
          }
        }
        return image;
      }
    
    
    //imageType , zxing支持的图像类型有三种,黑白颜色的默认为BufferedImage.TYPE_BYTE_BINARY = 12,图像不带透明度alpha   最多是4bit的的图像
    TYPE_INT_RGB 这个是不带alpha的8bit图像
    TYPE_INT_ARGB
    这个带alpha的8bit图像

    java.awt.image.BufferedImage.BufferedImage(int width, int height, int imageType)

    谢谢浏览

     参考链接:

    关于JAVA实现二维码以及添加二维码LOGO

    https://www.cnblogs.com/qwqwQAQ/p/8118109.html

    JAVA实现基于ZXing的二维码自动生成与图片合成

    https://blog.csdn.net/mruso/article/details/79744670

    Java通过Zxing生成二维码

    http://blog.51cto.com/9732420/1742136

    开源项目地址

    https://github.com/zxing/zxing

  • 相关阅读:
    php多态
    ssl certificate problem: self signed certificate in certificate chain
    test plugin
    open specific port on ubuntu
    junit vs testng
    jersey rest service
    toast master
    use curl to test java webservice
    update folder access
    elk
  • 原文地址:https://www.cnblogs.com/gne-hwz/p/9445466.html
Copyright © 2011-2022 走看看