天天看點

生成帶圖檔無白邊的二維碼

二維碼

轉載請注明出處:https://blog.csdn.net/u013173247/article/details/81748481

二維碼又稱二維條碼,常見的二維碼為QR Code,QR全稱Quick Response,是一個近幾年來移動裝置上超流行的一種編碼方式,它比傳統的Bar Code條形碼能存更多的資訊,也能表示更多的資料類型。

上面都是百度百科複制的,知道咱們生成的是矩陣二維碼就行。

本文是maven工程使用zxing 3.3.0的版本生成可自定義圖檔的二維碼,并且可以去除二維碼白邊。(生成二維碼有白邊,或二維碼内容多少改變有白邊的同學請看這裡)。

maven引入jar:

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

如果不是maven工程,可以直接下載下傳 jar包下載下傳

準備工作做完了,開始正文。

package com.neusoft.saas.contactcentre.controller.qrCode;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Hashtable;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class QRCodeFactory {  

    public static String EncodeQRCODE(String contents, int width, int height,
            String iconImagePath, String codePath,String ImageName) 
                    throws IOException, WriterException{ 
        try{
            if(width == ){
                width = ; // 二維碼圖檔寬度430
            }
            if(height == ){
                height = ; // 二維碼圖檔高度430 
            }
            File testFile = new File(codePath);
            if(!testFile .exists()){
                testFile.mkdir();//建立目錄
            }
            testFile = new File(codePath,ImageName);
            if(!testFile .exists()){
                testFile.createNewFile();//建立檔案
            }
            String format = "png";// 二維碼的圖檔格式png  

            Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();  
             // 指定糾錯等級,糾錯級别(L %、M %、Q %、H %)  
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);  
            // 内容所使用字元集編碼  
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");     
//          hints.put(EncodeHintType.MAX_SIZE, );//設定圖檔的最大值  
//          hints.put(EncodeHintType.MIN_SIZE, );//設定圖檔的最小值  
            hints.put(EncodeHintType.MARGIN, );   //設定白邊 

            BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,//要編碼的内容  
                    //編碼類型,目前zxing支援:Aztec D,CODABAR D format,Code  D,Code  D ,Code  D,  
                    //Data Matrix D , EAN- D,EAN- D,ITF (Interleaved Two of Five) D,  
                    //MaxiCode D barcode,PDF417,QR Code D,RSS ,RSS EXPANDED,UPC-A D,UPC-E D,UPC/EAN extension,UPC_EAN_EXTENSION  
                    BarcodeFormat.QR_CODE,  
                    width, //條形碼的寬度  
                    height, //條形碼的高度  
                    hints);//生成條形碼時的一些配置,此項可選  

            // 生成二維碼
            MatrixToImageWriter.writeToFile(bitMatrix, format, testFile,iconImagePath);
            return codePath+ImageName;
        } catch (IOException e) {
            System.err.println("圖檔讀取異常 : "+e.getMessage());
        } catch (WriterException e) {
            System.err.println("圖檔輸出異常 :"+e.getMessage());
        }
        return null;
    }    
    public static void main(String[] args) throws Exception {  
        try {  
            String contents = "https://blog.csdn.net/u013173247/article/details/41676495";
            String codeIconPath = "src/main/resources/view/src/static/images/QRCodeIconImg.png";
            String codePath =  System.getProperty("user.dir")+"/testQrcode/";
            String pngStr = new Date().getTime()+".png";
            String qrcodeImagePath = codePath + pngStr;
            EncodeQRCODE(contents,, , codeIconPath, codePath,pngStr);  
            if(qrcodeImagePath != null){
                File file = new File(qrcodeImagePath);
                String base64 = ImageUtil.encodeImgageToBase64(file);
                base64 = base64.replaceAll("\r|\n", "");
//              if (!file.exists()) {
//                  System.out.println("删除檔案失敗:" + qrcodeImagePath + "剛生成的file不存在!");
//              } else {
//                  if (file.isFile()){
//                      file.delete();
//                  }
//              }
                System.out.println("base64");
                System.out.println(base64);
            }else{
                System.out.println("報錯了!");
            }
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}
           

生成的二維碼如下

生成帶圖檔無白邊的二維碼

上圖二維碼有很大的白邊,看下源碼為什麼有白邊。從這行開始找

BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,//要編碼的内容  
                    //編碼類型,目前zxing支援:Aztec D,CODABAR D format,Code  D,Code  D ,Code  D,  
                    //Data Matrix D , EAN- D,EAN- D,ITF (Interleaved Two of Five) D,  
                    //MaxiCode D barcode,PDF417,QR Code D,RSS ,RSS EXPANDED,UPC-A D,UPC-E D,UPC/EAN extension,UPC_EAN_EXTENSION  
                    BarcodeFormat.QR_CODE,  
                    width, //條形碼的寬度  
                    height, //條形碼的高度  
                    hints);//生成條形碼時的一些配置,此項可選  
           

往裡跳

case QR_CODE:
        writer = new QRCodeWriter();
        break;
      case CODE_39:
        writer = new Code39Writer();
        break;
      case CODE_93:
        writer = new Code93Writer();
        break;
      case CODE_128:
        writer = new Code128Writer();
        break;
      case ITF:
        writer = new ITFWriter();
        break;
      case PDF_417:
        writer = new PDF417Writer();
        break;
      case CODABAR:
        writer = new CodaBarWriter();
        break;
      case DATA_MATRIX:
        writer = new DataMatrixWriter();
        break;
      case AZTEC:
        writer = new AztecWriter();
        break;
      default:
        throw new IllegalArgumentException("No encoder available for format " + format);
    }
    return writer.encode(contents, format, width, height, hints);
           

writer.encode(contents, format, width, height, hints)繼續往裡找

ErrorCorrectionLevel errorCorrectionLevel = ErrorCorrectionLevel.L;
    int quietZone = QUIET_ZONE_SIZE;
    if (hints != null) {
      if (hints.containsKey(EncodeHintType.ERROR_CORRECTION)) {
        errorCorrectionLevel = ErrorCorrectionLevel.valueOf(hints.get(EncodeHintType.ERROR_CORRECTION).toString());
      }
      if (hints.containsKey(EncodeHintType.MARGIN)) {
        quietZone = Integer.parseInt(hints.get(EncodeHintType.MARGIN).toString());
      }
    }

    QRCode code = Encoder.encode(contents, errorCorrectionLevel, hints);
    return renderResult(code, width, height, quietZone);
           

QRCode code = Encoder.encode(contents, errorCorrectionLevel, hints);這行繼續往裡找

//  Choose the mask pattern and set to "qrCode".
    int dimension = version.getDimensionForVersion();
    ByteMatrix matrix = new ByteMatrix(dimension, dimension);
    int maskPattern = chooseMaskPattern(finalBits, ecLevel, version, matrix);
    qrCode.setMaskPattern(maskPattern);

    // Build the matrix and set it to "qrCode".
    MatrixUtil.buildMatrix(finalBits, ecLevel, version, maskPattern, matrix);
    qrCode.setMatrix(matrix);
           

注意!!!

int dimension = version.getDimensionForVersion();
           

往裡找會發現

public int getDimensionForVersion() {
    return  +  * versionNumber;
  }
           

根據版本号計算出的值,本人的versionNumber值是10

dimension 值為57

main方法中要生成的是280

280/57=4餘52

可以跳轉生成的資料,比如此二維碼可以跳轉main方法中的值為228

問題來了:如果内容長度不固定,還想沒有白邊,怎麼辦?

接着往下看。

寫一個去除白邊的方法

public static BitMatrix deleteWhite(BitMatrix matrix){  
        int[] rec = matrix.getEnclosingRectangle();  
        int resWidth = rec[];  
        int resHeight = rec[];  
        BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);  
        resMatrix.clear();  
        for (int i = ; i < resWidth; i++) {  
            for (int j = ; j < resHeight; j++) { 
                if (matrix.get(i + rec[], j + rec[]))  
                    resMatrix.set(i, j);  
            }  
        }  
        return resMatrix;  
    }
           

在代碼中調用

BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,//要編碼的内容  
                    //編碼類型,目前zxing支援:Aztec D,CODABAR D format,Code  D,Code  D ,Code  D,  
                    //Data Matrix D , EAN- D,EAN- D,ITF (Interleaved Two of Five) D,  
                    //MaxiCode D barcode,PDF417,QR Code D,RSS ,RSS EXPANDED,UPC-A D,UPC-E D,UPC/EAN extension,UPC_EAN_EXTENSION  
                    BarcodeFormat.QR_CODE,  
                    width, //條形碼的寬度  
                    height, //條形碼的高度  
                    hints);//生成條形碼時的一些配置,此項可選  

            // 生成二維碼  
//          File outputFile = new File(codePath,new Date().getTime()+".png");//指定輸出路徑  
            bitMatrix = deleteWhite(bitMatrix);  
            MatrixToImageWriter.writeToFile(bitMatrix, format, testFile,iconImagePath);
           

生成的會是沒有任何白邊的二維碼

問題又來了:如果我就想要固定大小白邊的怎麼辦?

修改下去除白邊方法的代碼

public static BitMatrix deleteWhite(BitMatrix matrix){  
        int[] rec = matrix.getEnclosingRectangle();
        int resWidth = rec[] + ;
        int resHeight = rec[] + ;
        BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);  
        resMatrix.clear();  
        for (int i = ; i < resWidth; i++) {  
            for (int j = ; j < resHeight; j++) {  
                if (matrix.get(i + rec[], j + rec[]))  
                    resMatrix.set(i+, j+);  
            }  
        }  
        return resMatrix;  
    }
           

上面代碼就是給二位碼添加1的白邊

完成。最後附上源碼下載下傳連結源碼下載下傳

轉載請注明出處:https://blog.csdn.net/u013173247/article/details/81748481