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

  • 相关阅读:
    数组有没有length()这个方法? String有没有length()这个方法?
    序列化接口的id有什么用?
    如何进行Hibernate的性能优化?
    构造器Constructor是否可被override?
    Collection框架中实现比较要实现什么接口?
    ArrayList如何实现插入的数据按自定义的方式有序存放?
    Java中会存在内存泄漏吗,请简单描述?
    List 和 Map 区别?
    面向对象的特征有哪些?
    垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?
  • 原文地址:https://www.cnblogs.com/gne-hwz/p/9445466.html
Copyright © 2011-2022 走看看