Nani? Two-dimensional code size actually not be able to customize the size?

In recent work, a junior partner encountered a problem on two-dimensional code: Use zxing, given the size of the two-dimensional code specified size, when the size is smaller than a certain range, the resulting two-dimensional code size and size requirements are quite different. For example: For example, I have given the two-dimensional code generation size is 36 * ️36px, two-dimensional code is generated out of the actual size of 21 * 21 px.

principle

If the two-dimensional code mechanism for a better understanding of the students, should know, two-dimensional code with good error correction capability and a large amount of information carrying capacity. In order to achieve the different information processing scales better performance of the two-dimensional code provides 40 levels of specifications, to generate a size range of 21 to 177 * 21 * 177.

In our scenario above, we use ZXing to generate two-dimensional code is version 1, the two-dimensional code is returned back to a 21 * 21 matrix information, given the size of 36 * 36 is not an integer multiple of 21, receiving only a 21 * 21 size information, so we will be transformed into two-dimensional code information matrix picture when only 21 * 21 px generate two-dimensional code.

Specific generation principle and the details in this article has done a very detailed description, see the two-dimensional code (QR code) to generate the basic structure and principles . Here I list only the knowledge associated with this article:

1、Version

There are different versions of the two-dimensional code 1-40, and each version is inherently "symbol structure." (I.e., the square black and white two-dimensional code point) starts from version (21 symbols × 21 symbols), the longitudinal and transverse directions to each 4-symbol increments, up to the version 40 (177 symbols × 177 yards membered) .

2, error correction level

That fault rate, a total of four levels, the higher level error correction capability is also increased accordingly, but since the amount of data is increased, can also become large encoding sizes.

Error correction level Fault tolerance
L About 7%
M About 15%
THE About 25%
Q About 30%

3, encoding

I.e., QR code encoding, two-dimensional code information can be encoded in numbers, alphanumeric, binary, Chinese, Japanese or the like.

How to solve

From the principle that the two-dimensional code, the two-dimensional code size is always 40 versions of a multiple of the size, and therefore smaller size for the generation of two-dimensional code, the two-dimensional code can be adjusted version of fault tolerance and encoding to demand as much as possible with a given size. In our production environment, we are using utf8 to encode information, so two-dimensional code size depends on the version and error correction level selected. Specific ideas are:

  • 1, find the closest version of a given size
  • 2, to determine whether the version can accommodate the given information to find the optimal level of fault tolerance
  • 3, and returns the size of fault tolerance level code encoded as follows:

public class QrCodeTest {
    //各尺寸最大容量,具体数据请参考 https://www.qrcode.com/zh/about/version.html
    static final int[][] VERSION_ERROR_ARR = new int[][]{
            {10,8,7,4},{20,16,12,8},{32,26,20,15},{48,38,28,21},
            {65,52,37,27},{82,65,45,36},{95,75,53,39},{118,93,66,52},
            {141,111,80,60},{167,131,93,74},{198,155,109,85},{226,177,125,96},
            {262,204,149,109},{282,223,159,120},{320,254,180,136},{361,277,198,154},
            {397,310,224,173},{442,345,243,191},{488,384,272,208},{528,410,297,235},
            {572,438,314,248},{618,480,348,270},{672,528,376,284},{721,561,407,315},
            {784,614,440,330},{842,652,462,365},{902,692,496,385},{940,732,534,405},
            {1002,778,559,430},{1066,843,604,457},{1132,894,634,486},{1201,947,684,518},
            {1273,1002,719,553},{1347,1060,756,590},{1417,1113,790,605},{1496,1176,832,647},
            {1577,1224,876,673},{1661,1292,923,701},{1729,1362,972,750},{1817,1435,1024,784}
    };

    public static int[] getQrCodeVersionAndError(String str, int size) throws Exception{
        if(21 > size){
            throw new IllegalAccessException("二维码尺寸不能小于21*21px");
        }
        
        //查找最接近给定尺寸的version
        int tVersion = (int)Math.floor((size - 21)/4.0);
        int errorCode = -1;
        int len = str.length();
        int minLen = len;

        int tLen1 = Math.abs(size - tVersion * 4 - 21);
        int tLen2 = Math.abs(size - (tVersion + 1) * 4 - 21);
        int version = tLen1 <= tLen2 ? tVersion : tVersion + 1;

        if(VERSION_ERROR_ARR[version][0] > len){
            return new int[]{version, 0};
        }
        //尺寸过小,不能容纳用户给定数据    
        for(int i = version+1; i < VERSION_ERROR_ARR.length; i++){
            for(int j = 0; j < VERSION_ERROR_ARR[i].length; j++){
                int min = Math.abs(len - VERSION_ERROR_ARR[i][j]);
                if(min == 0){
                    minLen = min;
                    version = i;
                    errorCode = j;
                    break;
                }else if(min <= minLen){
                    minLen = min;
                    version = i;
                    errorCode = j;
                }
            }

            if(-1 != errorCode){
                break;
            }
        }

        if(-1 == errorCode){
            throw new IllegalAccessException("该字符串内容过大");
        }

        return new int[]{version, errorCode};
    }

    public static void main(String[] args) throws Exception{
        print("hello",21);
        print("hello",22);
        print("hellohellohellohellohello",42);
        print("hello",43);
    }

    private static void print(String str, int size) throws Exception{
        int[] result = getQrCodeVersionAndError(str,size);
        System.out.println(str+","+size + ":["+result[0] + "," + result[1]+"]");
    }
}

复制代码

thank

Guess you like

Origin juejin.im/post/5d88e153518825095f100dd4