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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM