天天看點

JAVA生成二維碼(二)深度處理

1.寫這個部落格的目的

解決JAVA生成二維碼(一)中的一些問題。

2.解讀排錯率,編碼模式,版本問題.以下都是自己測試中存在的問題

1.排錯率

排錯的原理是二維碼在編碼過程中進行了備援,就像是123被編碼成123123,這樣隻要掃描到一部分二維碼圖檔,二維碼内容還是可以被全部讀到。

設定二維碼排錯率,可選L(7%)、M(15%)、Q(25%)、H(30%),排錯率越高可存儲的資訊越少,但對二維碼清晰度的要求越小,即是指二維碼圖示被遮擋多少後,仍可以被掃描出來的能力。排錯率越高,則二維碼圖檔能被遮擋的部分越多。

2.編碼模式

編碼模式:Numeric(N-數字):Binary(B-二進制):Alphanumeric(A-英文字母)

不同的内容使用對應的編碼格式

3.版本問題(1-40)

即二維碼的規格,QR碼符号共有40種規格的矩陣(一般為黑白色),從21x21(版本1),到177x177(版本40),每一版本符号比前一版本每邊增加4個子產品。

問題一:排錯率選太高導緻内容過長,二維碼生成失敗

如運作如下代碼:

package com.wangcong;
 
import com.swetake.util.Qrcode;
 
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
 
public class two {
    public static void main(String[] args) {
        String imgPath = "E:/code.png";         // 二維碼儲存路徑
        // 跳轉的内容,如果http://則當做文字處理
        String content = "好好學習,天天向上,努力敲代碼學JAVA";
        
        // 建立封裝類
        QrCodeAssis assis = new QrCodeAssis(imgPath, content);
        boolean result =  assis.createCode(480, 480);
        if (result) {
            System.out.println("二維碼生成成功!");
        } else {
            System.out.println("二維碼生成失敗!");
        }
    }
}


/**
 * 使用QRCode生成二維碼
 */
class QrCodeAssis{
    private String imgPath;         // 二維碼儲存路徑
    private String content;         // 二維碼内容
 
    /**
     * imgPath 二維碼儲存路徑, content 二維碼内容]
     */
    QrCodeAssis(String imgPath, String content) {
        this.imgPath = imgPath;
        this.content = content;
    }
    /**
     * boolean 二維碼是否生成成功
     */
    boolean createCode(int width, int height) {
        boolean flag = true;
        try {
            Qrcode qrcode = new Qrcode();           // 建立Qrcode對象
            // 排錯率可選(%)-L(7):M(15):Q(25):H(30)
            qrcode.setQrcodeErrorCorrect('Q');
            // 編碼模式-Numeric(N-數字):Binary(B-二進制):Alphanumeric(A-英文字母)
            qrcode.setQrcodeEncodeMode('B');
            qrcode.setQrcodeVersion(3);             // 設定版本(可選)
 
            width = width >= 100 ? width : 100;     // 寬度至少100
            height = height >= 100 ? height: 100;   // 高度至少100
            // 建立畫布和畫圖裝置
            BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
            Graphics2D draw = img.createGraphics();
            draw.setBackground(Color.WHITE);        // 設定背景色
            draw.clearRect(0, 0, width, height);    // 清空原始内容
            draw.setColor(Color.BLACK);             // 設定前景色
 
            int posOff = 2;     // 設定偏移量,避免輸出點重疊
            // 設定内容編碼
            byte[] codeContent = this.content.getBytes("utf-8");
            // 生成二維數組,500是内容大小,根據自己的内容大小進行設定
            if (codeContent.length > 0 && codeContent.length < 600) {
                boolean[][] qrcodeOut = qrcode.calQrcode(codeContent);
                // 将内容寫入到圖檔中
                for (int i = 0; i < qrcodeOut.length; i++) {
                    for (int j = 0; j < qrcodeOut.length; j++) {
                        // 如果目前位置有像素點
                        if (qrcodeOut[j][i]){
                           // 寫入圖檔
                           draw.fillRect(j * 16 + posOff, i * 16 + posOff, 16, 16);
                       }
                    }
                }
            }
            
            draw.dispose();                                // 關閉畫圖裝置
            img.flush();                                   // 重新整理緩沖區
            File file = new File(imgPath);
            ImageIO.write(img, "png", file);    // 儲存圖檔
 
        } catch (Exception e) {
            e.printStackTrace();
            flag = false;
        }
        return flag;
    }
}

           

運作結果如下;

JAVA生成二維碼(二)深度處理

解決方案:可适當将版本調大,(類似與擴大二維碼容器,讓二維碼能存放更多的内容)

問題二:将版本調大之後,導緻生成的二維碼不全,掃描沒反應(問題一的一個并發問題)問題一生成的二維碼如下圖:

JAVA生成二維碼(二)深度處理

掃描二維碼不會有反應

解決方案:認真解讀代碼會發現提供的createCode方法有兩個參數,分别代表的是圖檔的畫布BufferedImage的寬和高隻需要适當調整一下代碼boolean result = assis.createCode(480, 480);内的2個參數即可:如下代碼:

package com.wangcong;
 
import com.swetake.util.Qrcode;
 
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
 
public class two {
    public static void main(String[] args) {
        String imgPath = "E:/code.png";         // 二維碼儲存路徑
        // 跳轉的内容,如果http://則當做文字處理
        String content = "好好學習,天天向上,努力敲代碼學JAVA";
        
        // 建立封裝類
        QrCodeAssis assis = new QrCodeAssis(imgPath, content);
        boolean result =  assis.createCode(700, 700);
        if (result) {
            System.out.println("二維碼生成成功!");
        } else {
            System.out.println("二維碼生成失敗!");
        }
    }
}


/**
 * 使用QRCode生成二維碼
 */
class QrCodeAssis{
    private String imgPath;         // 二維碼儲存路徑
    private String content;         // 二維碼内容
 
    /**
     * imgPath 二維碼儲存路徑, content 二維碼内容]
     */
    QrCodeAssis(String imgPath, String content) {
        this.imgPath = imgPath;
        this.content = content;
    }
    /**
     * boolean 二維碼是否生成成功
     */
    boolean createCode(int width, int height) {
        boolean flag = true;
        try {
            Qrcode qrcode = new Qrcode();           // 建立Qrcode對象
            // 排錯率可選(%)-L(7):M(15):Q(25):H(30)
            qrcode.setQrcodeErrorCorrect('Q');
            // 編碼模式-Numeric(N-數字):Binary(B-二進制):KanJi(K-漢字):Alphanumeric(A-英文字母)
            qrcode.setQrcodeEncodeMode('B');
            qrcode.setQrcodeVersion(5);             // 設定版本(可選)
 
            width = width >= 100 ? width : 100;     // 寬度至少100
            height = height >= 100 ? height: 100;   // 高度至少100
            // 建立畫布和畫圖裝置
            BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
            Graphics2D draw = img.createGraphics();
            draw.setBackground(Color.WHITE);        // 設定背景色
            draw.clearRect(0, 0, width, height);    // 清空原始内容
            draw.setColor(Color.BLACK);             // 設定前景色
 
            int posOff = 2;     // 設定偏移量,避免輸出點重疊
            // 設定内容編碼
            byte[] codeContent = this.content.getBytes("utf-8");
            // 生成二維數組,500是内容大小,根據自己的内容大小進行設定
            if (codeContent.length > 0 && codeContent.length < 600) {
                boolean[][] qrcodeOut = qrcode.calQrcode(codeContent);
                // 将内容寫入到圖檔中
                for (int i = 0; i < qrcodeOut.length; i++) {
                    for (int j = 0; j < qrcodeOut.length; j++) {
                        // 如果目前位置有像素點
                        if (qrcodeOut[j][i]){
                           // 寫入圖檔
                           draw.fillRect(j * 16 + posOff, i * 16 + posOff, 16, 16);
                       }
                    }
                }
            }
            
            draw.dispose();                                // 關閉畫圖裝置
            img.flush();                                   // 重新整理緩沖區
            File file = new File(imgPath);
            ImageIO.write(img, "png", file);    // 儲存圖檔
 
        } catch (Exception e) {
            e.printStackTrace();
            flag = false;
        }
        return flag;
    }
}

           

生成的二維碼如下圖:

JAVA生成二維碼(二)深度處理

掃描結果如下圖:

JAVA生成二維碼(二)深度處理

問題三:編碼模式選擇錯誤:導緻生成的二維碼掃描沒結果(生成了一個本人部落格的網址卻不能掃描)例如如下代碼:

package com.wangcong;
 
import com.swetake.util.Qrcode;
 
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
 
public class two {
    public static void main(String[] args) {
        String imgPath = "E:/code.png";         // 二維碼儲存路徑
        // 跳轉的内容,如果http://則當做文字處理
        String content = "https://blog.csdn.net/weixin_44255950";
        
        // 建立封裝類
        QrCodeAssis assis = new QrCodeAssis(imgPath, content);
        boolean result =  assis.createCode(480,480);
        if (result) {
            System.out.println("二維碼生成成功!");
        } else {
            System.out.println("二維碼生成失敗!");
        }
    }
}


/**
 * 使用QRCode生成二維碼
 */
class QrCodeAssis{
    private String imgPath;         // 二維碼儲存路徑
    private String content;         // 二維碼内容
 
    /**
     * imgPath 二維碼儲存路徑, content 二維碼内容]
     */
    QrCodeAssis(String imgPath, String content) {
        this.imgPath = imgPath;
        this.content = content;
    }
    /**
     * boolean 二維碼是否生成成功
     */
    boolean createCode(int width, int height) {
        boolean flag = true;
        try {
            Qrcode qrcode = new Qrcode();           // 建立Qrcode對象
            // 排錯率可選(%)-L(7):M(15):Q(25):H(30)
            qrcode.setQrcodeErrorCorrect('L');
            // 編碼模式-Numeric(N-數字):Binary(B-二進制):KanJi(K-漢字):Alphanumeric(A-英文字母)
            qrcode.setQrcodeEncodeMode('N');
            qrcode.setQrcodeVersion(3);             // 設定版本(可選)
 
            width = width >= 100 ? width : 100;     // 寬度至少100
            height = height >= 100 ? height: 100;   // 高度至少100
            // 建立畫布和畫圖裝置
            BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
            Graphics2D draw = img.createGraphics();
            draw.setBackground(Color.WHITE);        // 設定背景色
            draw.clearRect(0, 0, width, height);    // 清空原始内容
            draw.setColor(Color.BLACK);             // 設定前景色
 
            int posOff = 2;     // 設定偏移量,避免輸出點重疊
            // 設定内容編碼
            byte[] codeContent = this.content.getBytes("utf-8");
            // 生成二維數組,500是内容大小,根據自己的内容大小進行設定
            if (codeContent.length > 0 && codeContent.length < 600) {
                boolean[][] qrcodeOut = qrcode.calQrcode(codeContent);
                // 将内容寫入到圖檔中
                for (int i = 0; i < qrcodeOut.length; i++) {
                    for (int j = 0; j < qrcodeOut.length; j++) {
                        // 如果目前位置有像素點
                        if (qrcodeOut[j][i]){
                           // 寫入圖檔
                           draw.fillRect(j * 16 + posOff, i * 16 + posOff, 16, 16);
                       }
                    }
                }
            }
            
            draw.dispose();                                // 關閉畫圖裝置
            img.flush();                                   // 重新整理緩沖區
            File file = new File(imgPath);
            ImageIO.write(img, "png", file);    // 儲存圖檔
 
        } catch (Exception e) {
            e.printStackTrace();
            flag = false;
        }
        return flag;
    }
}

           

生成的二維碼如下圖:

JAVA生成二維碼(二)深度處理

内容存放的是本人的部落格網址,但是掃描沒有結果:

解決方案:講編碼模式改成B

生成的二維碼如下圖:

JAVA生成二維碼(二)深度處理

掃描結果為:

JAVA生成二維碼(二)深度處理

最後,通過本人個人部落格可以看到本人粉絲不多,喜歡的人也不多,求一波粉絲,求一波喜歡,本人也會經常發部落格