博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
二维码生成2
阅读量:7014 次
发布时间:2019-06-28

本文共 9956 字,大约阅读时间需要 33 分钟。

上一篇中介绍了通过类库ThoughtWorks.QRCode.dll生成二维码的简单应用,并对类库ThoughtWorks.QRCode.dll做了个简单的封装,这次在上次的基础上做修改,增加了可以在二维码中间增加自定义头像或图标。

下面这篇文章详细介绍了二维码的原理,因为二维码中间大部分区域都是一些无用码,并不影响我们对二维码正常信息的读取,所以我们可以把一张自己的头像,或是公司商标等放在二维码的中间。

要在二维码中间放置商标,而不影响二维码的读取,我们必须设置二维码的纠错级别 为高:

1 _QRCode.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H;

若不需要中间放图片,正常情况下,我们设置为M即可:

1  _QRCode.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;

要注意:当 _QRCode.QRCodeErrorCorrect级别不同时,二维码中可以包含的内容长度是不同的:

当 _QRCode.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M时,最多可包含2332个字节数据,最少可包含15个字节数据;

当 _QRCode.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H时,最多只可包含1274个字节数据,最少可包含8个字节数据;

具体支持多少个字节数据,与属性数值有关。

我们可以通过我简单类中的以下几个方法,来设置二维码的中间图片:

1         ///  2         /// 设置二维码中间图片 3         ///  4         /// 图片文件名,包含路径 5         public void SetFillImage(string fileName) 6         { 7             SetFillImage(fileName, 100, 100); 8         } 9         /// 10         /// 设置二维码中间图片11         /// 12         /// 图片文件名,包含路径13         /// 图片宽度14         /// 图片高度15         public void SetFillImage(string fileName, int width, int height)16         {17             if (!string.IsNullOrEmpty(fileName)) {18                 if (File.Exists(fileName)) {19                     SetFillImage(Image.FromFile(fileName), width, height);20                 }21             }22         }23         /// 24         /// 设置二维码中间图片25         /// 26         /// 图上片IMAGE对象27         public void SetFillImage(Image bitmap)28         {29             SetFillImage(bitmap, 100, 100);30         }31         /// 32         /// 设置二维码中间图片33         /// 34         /// 图上片IMAGE对象35         /// 图片宽度36         /// 图片高度37         public void SetFillImage(Image bitmap, int width, int height)38         {39             fileImage = bitmap;40             _QRCode.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H;41             this._maskWidth = width;42             this._maskHeight = height;43         }

设置图片时,会自动设置 属性为H。

为了保证二维码能正确识别,中间图片的大小最好为二维码大小的1/3到3/7之间,我设置为1/3大小的样子:

1         int maskWidth = Math.Min((int)(this.Width / 3), _maskWidth);     //最终图片宽度2         int maskHeight = Math.Min((int)(this.Height / 3), _maskHeight);  //最终图片高度3 4         int maskLeft = (this.Width - maskWidth) / 2;             //图片位置5         int maskTop = (this.Height - maskHeight) / 2;                  //图片位置

 

这样在调用Encode方法生成二维码时,会自动将设置好的图片放到二维码的中间。

具体调用方法:

1             ErWeiMa.ErWeiMa er = new ErWeiMa.ErWeiMa();2             er.SetFillImage(Server.MapPath("~/t.jpg"));3             this.img1.Src = er.Encode("中华人民共和国");

生成的二维码如下所示:

源代码:

1     public class ErWeiMa  2     {  3         private QRCodeEncoder _QRCode;  4         private Encoding encoding;  5   6         public ErWeiMa()  7         {  8             _QRCode = new QRCodeEncoder();  9             _QRCode.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE; 10             _QRCode.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M; 11             _QRCode.QRCodeScale = 4; 12  13             encoding = Encoding.UTF8; 14         } 15  16         public static ErWeiMa GetInstance() 17         { 18             return new ErWeiMa(); 19         } 20  21         ///  22         /// 获取二维码图像base64字符串,可直接赋值给img对象的src显示 23         /// 默认编码UTF8,QRCodeEncoder默认值为Unicode 24         ///  25         /// 编码内容 26         /// 
二维码图像base64字符串
27 public string Encode(string content) 28 { 29 return this.Encode(content, encoding); 30 } 31 /// 32 /// 获取二维码图像base64字符串,可直接赋值给img对象的src显示 33 /// 34 /// 编码内容 35 /// 编码类型 36 ///
二维码图像base64字符串
37 public string Encode(string content,Encoding encoding) 38 { 39 this.encoding = encoding; 40 this.InitVersion(content); 41 using (var ms = new MemoryStream()) 42 using (Bitmap image = _QRCode.Encode(content, encoding)) 43 { 44 this.Width = image.Width; 45 this.Height = image.Height; 46 FileImage(image); 47 image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); 48 return "data:image/jpeg;base64," + Convert.ToBase64String(ms.ToArray()); 49 } 50 } 51 52 private void FileImage(Bitmap source) 53 { 54 int maskWidth = Math.Min((int)(this.Width / 3), _maskWidth); 55 int maskHeight = Math.Min((int)(this.Height / 3), _maskHeight); 56 57 int maskLeft = (this.Width - maskWidth) / 2; 58 int maskTop = (this.Height - maskHeight) / 2; 59 60 using (Graphics g = Graphics.FromImage(source)) 61 { 62 g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 63 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 64 g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 65 //g.FillRectangle(new SolidBrush(Color.Red), maskLeft, maskTop, maskWidth, maskHeight); 66 ////g.DrawImage( 67 if (fileImage != null) { 68 g.DrawImage(fileImage, maskLeft, maskTop, maskWidth, maskHeight); 69 } 70 } 71 } 72 73 /// 74 /// 根据编码内容自动获取QRCodeVersion值 75 /// 76 /// 77 private void InitVersion(string content) 78 { 79 int length = encoding.GetByteCount(content); 80 81 if (length > GetArray()[40]) { 82 throw new Exception("The content too length;Must be shorter than " + GetArray()[40].ToString() + "byte"); ; 83 } 84 85 _QRCode.QRCodeVersion = GetIndex(length); 86 } 87 88 /// 89 /// 每个QRCodeVersion值对应支持最长字节数 90 /// 91 private int[] array = new int[41] {
15,15,27,43,63,85,107,123,153,181,214,252,288,332,363,413,451,505,561,625,667,712,780,858,912,998,1060,1126,1191,1265,1371,1453,1539,1629,1723,1810,1912,1990,2100,2214,2332 }; 92 /// 93 /// QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H时 每个QRCodeVersion值对应支持最长字节数 94 /// 95 private int[] array2 = new int[41] { 8, 8, 15, 25, 35, 45, 59, 65, 85, 99, 120, 138, 156, 178, 195, 221, 251, 281, 311, 339, 383, 404, 440, 462, 512, 536, 594, 626, 659, 699, 743, 791, 843, 899, 959, 984, 1052, 1094, 1140, 1220, 1274 }; 96 97 private int[] GetArray() 98 { 99 switch (_QRCode.QRCodeErrorCorrect)100 {101 case QRCodeEncoder.ERROR_CORRECTION.H:102 return array2;103 case QRCodeEncoder.ERROR_CORRECTION.M:104 return array;105 default:106 return array;107 }108 }109 110 private int GetIndex(int length)111 {112 if (length <= GetArray()[0]) {113 return 0;114 }115 if (length == GetArray()[40]) {116 return 40;117 }118 119 return FindIndex(GetArray(), length, 0, 40);120 }121 122 private int FindIndex(int[] sourceArray, int findValue, int startIndex, int endIndex)123 {124 int mid = (startIndex + endIndex) % 2 == 0 ? (startIndex + endIndex) / 2 : (startIndex + endIndex) / 2 + 1;125 126 if (startIndex >= endIndex) {127 return startIndex;128 }129 130 if (findValue == sourceArray[mid])131 {132 return mid;133 }134 else if (findValue < sourceArray[mid])135 {136 if (findValue > sourceArray[mid - 1])137 {138 return mid;139 }140 return FindIndex(sourceArray,findValue, startIndex, mid - 1);141 }142 else {143 if (findValue < sourceArray[mid + 1])144 {145 return mid + 1;146 }147 return FindIndex(sourceArray,findValue, mid + 1, endIndex);148 }149 }150 151 private Image fileImage = null;152 153 /// 154 /// 设置二维码中间图片155 /// 156 /// 图片文件名,包含路径157 public void SetFillImage(string fileName)158 {159 SetFillImage(fileName, 100, 100);160 }161 /// 162 /// 设置二维码中间图片163 /// 164 /// 图片文件名,包含路径165 /// 图片宽度166 /// 图片高度167 public void SetFillImage(string fileName, int width, int height)168 {169 if (!string.IsNullOrEmpty(fileName)) {170 if (File.Exists(fileName)) {171 SetFillImage(Image.FromFile(fileName), width, height);172 }173 }174 }175 /// 176 /// 设置二维码中间图片177 /// 178 /// 图上片IMAGE对象179 public void SetFillImage(Image bitmap)180 {181 SetFillImage(bitmap, 100, 100);182 }183 /// 184 /// 设置二维码中间图片185 /// 186 /// 图上片IMAGE对象187 /// 图片宽度188 /// 图片高度189 public void SetFillImage(Image bitmap, int width, int height)190 {191 fileImage = bitmap;192 _QRCode.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H;193 this._maskWidth = width;194 this._maskHeight = height;195 }196 /// 197 /// 生成的二维码宽度198 /// 199 public int Width { get; set; }200 /// 201 /// 生成的二维码高度202 /// 203 public int Height { get; set; }204 205 private int _maskWidth = 0;206 private int _maskHeight = 0;207 }
View Code

ThoughtWorks.QRCode.dll类库地址,请参见我上一篇笔记。

 

转载于:https://www.cnblogs.com/maerge/p/6445545.html

你可能感兴趣的文章