二维码是什么

二维码 QR Code,全称为:Quick Response Code,最早用于日本汽车制造业追踪零部件。QR现有40个标准版本,4个微型版本。相比一维码(也就是我们目前还在常用的条码),拥有更高密度的编码,可存储的信息量更大。一维码只能存储字母和数字,二维码可容纳多达1850个大写字母或者2710个数字或者1108个字符或者500多个汉字,比条码存储量多了几十倍。另外,二维码可以把图片、声音、文字、等可以数字化的信息进行编码。

除此之外:二维码比一维码译码错误率要低得多(误码率不超过千分之一),保密性、防伪性更好,成本低廉,容易制作,让二维码使用更加广泛,越来越流行。

除了存储编码的数据,QR码里还含有一些基本标准里钦定的图样来帮助扫描软件快速识别和解码。

C# 实现二维码详解_QR Code

标准(ISO/IEC 18004)里是这样说的

C# 实现二维码详解_二维码_02

 更多的详解请查看​​这篇博客​

C# 实现

首先在NuGet引入ThoughtWorks.QRCode

C# 实现二维码详解_二维码_03

 生产二维码的时候用到ThoughtWorks.QRCode 的 QRCodeEncoder类

namespace ThoughtWorks.QRCode.Codec
{
public class QRCodeEncoder
{
public QRCodeEncoder();

public virtual Color QRCodeBackgroundColor { get; set; }
public virtual ENCODE_MODE QRCodeEncodeMode { get; set; }
public virtual ERROR_CORRECTION QRCodeErrorCorrect { get; set; }
public virtual Color QRCodeForegroundColor { get; set; }
public virtual int QRCodeScale { get; set; }
public virtual int QRCodeVersion { get; set; }

public virtual bool[][] calQrcode(byte[] qrcodeData);
public virtual int calStructureappendParity(sbyte[] originaldata);
public virtual Bitmap Encode(string content);
public virtual Bitmap Encode(string content, Encoding encoding);
public virtual void setStructureappend(int m, int n, int p);

public enum ENCODE_MODE
{
ALPHA_NUMERIC = 0,
NUMERIC = 1,
BYTE = 2
}
public enum ERROR_CORRECTION
{
L = 0,
M = 1,
Q = 2,
H = 3
}
}
}

ENCODE_MODE枚举是编码方式,因为我们的字符串里面可能存在中文,所以这里使用了BYTE,ALPHA_NUMERIC与NUMERIC只能编码数字

数字编码(NUMERIC):可编码0-9,10个数字,如果需要编码的数字的个数不是3的倍数,最后剩下的1或2位数会被转成4或7bits,其它的每3位数字会根据不同版本被编成 10,12,14bits

字符编码(ALPHA_NUMERIC) :可编码0-9,大写的A-Z,以及9个其他的字符(space $ % * + – . / :);

8位字节模式(BYTE) :可编码JIS X 0201的8位Latin/Kana字符集

除此之外,QR还提供了其他的编码方式,每一个编码方式都有其独有的id进行标识,这些标识会记录在数据区的前端,使得解码器可以根据二维码使用的编码方式对数据进行解码

      C# 实现二维码详解_数据_04

 ERROR_CORRECTION枚举是容错级别

L : 最大 7% 的错误能够被纠正;

M : 最大 15% 的错误能够被纠正;

Q : 最大 25% 的错误能够被纠正;

H : 最大 30% 的错误能够被纠正;

版本信息:即二维码的规格,QR码符号共有40种规格的矩阵(一般为黑白色),从21x21(版本1),到177x177(版本40),每一版本符号比前一版本每边增加4个模块。

177 = 21+(40-1)+4 = 21 +156.

 C# 实现二维码详解_c#_05

 C#调用生成二维码

        /// <summary>
/// 生成二维码
/// </summary>
/// <param name="strContent">二维码内容</param>
/// <param name="qrCodeEncodeMode">编码方式</param>
/// <param name="qrCodeScale">大小</param>
/// <param name="qrCodeVersion">版本</param>
/// <param name="qrCodeErrorCorrect">错误效验、错误更正</param>
/// <returns></returns>
public Bitmap CreateQRCodeBimap(string strContent, int qrCodeEncodeMode,int qrCodeScale,int qrCodeVersion,int qrCodeErrorCorrect)
{
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
//编码方式(BYTE能支持中文)
qrCodeEncodeMode = qrCodeEncodeMode > 2 ? 2 : qrCodeEncodeMode;
qrCodeEncoder.QRCodeEncodeMode = (QRCodeEncoder.ENCODE_MODE)qrCodeEncodeMode;
//大小(值越大生成的二维码图片像素越高)
qrCodeEncoder.QRCodeScale = qrCodeScale;
//版本
qrCodeEncoder.QRCodeVersion = qrCodeVersion;
//错误效验、错误更正
qrCodeErrorCorrect = qrCodeErrorCorrect > 3 ? 3 : qrCodeErrorCorrect;
qrCodeEncoder.QRCodeErrorCorrect = (QRCodeEncoder.ERROR_CORRECTION)qrCodeErrorCorrect;

return qrCodeEncoder.Encode(strContent, Encoding.GetEncoding("UTF-8"));//GB2312
}