Last article Two-Dimensional Code Generation This paper introduces the simple application of generating two-dimensional codes through the class library ThoughtWorks.QRCode.dll, and makes a simple encapsulation of the class library ThoughtWorks.QRCode.dll. Based on the last modification, the user-defined head image or icon can be added in the middle of the two-dimensional code.
The following article introduces the principle of two-dimensional code in detail, because most areas in the middle of the two-dimensional code are useless codes, which does not affect our normal reading of two-dimensional code information, so we can put a head image of ourselves or company trademarks in the middle of the two-dimensional code.
http://developer.51cto.com/art/201310/414082_all.htm
In order to place a trademark in the middle of the two-dimensional code without affecting the reading of the two-dimensional code, we must set the error correction level of the two-dimensional code. QRCodeErrorCorrect For high:
1 _QRCode.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H;
If you don't need to put pictures in the middle, normally, we set it up QRCodeErrorCorrect For M:
1 _QRCode.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
Note: When the _QRCode.QRCodeErrorCorrect level is different, the content length that can be included in two-dimensional codes is different:
When _QRCode.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M, it can contain up to 2332 byte data and at least 15 byte data.
When _QRCode.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H, it can contain up to 1274 bytes of data and at least 8 bytes of data.
Specifically support how many bytes of data, and attributes QRCodeVersion The values are relevant.
We can use the following methods in my simple class to set the middle picture of the two-dimensional code:
1 /// <summary> 2 /// Setting 2-D Code Intermediate Picture 3 /// </summary> 4 /// <param name="fileName">Image file name, including path</param> 5 public void SetFillImage(string fileName) 6 { 7 SetFillImage(fileName, 100, 100); 8 } 9 /// <summary> 10 /// Setting 2-D Code Intermediate Picture 11 /// </summary> 12 /// <param name="fileName">Image file name, including path</param> 13 /// <param name="width">image width</param> 14 /// <param name="height">Picture height</param> 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 /// <summary> 24 /// Setting 2-D Code Intermediate Picture 25 /// </summary> 26 /// <param name="bitmap">Plot above IMAGE object</param> 27 public void SetFillImage(Image bitmap) 28 { 29 SetFillImage(bitmap, 100, 100); 30 } 31 /// <summary> 32 /// Setting 2-D Code Intermediate Picture 33 /// </summary> 34 /// <param name="bitmap">Plot above IMAGE object</param> 35 /// <param name="width">image width</param> 36 /// <param name="height">Picture height</param> 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 }
When setting pictures, they will be set automatically QRCodeErrorCorrect Attribute H.
In order to ensure that the two-dimensional code can be correctly recognized, the size of the middle picture should be between 1/3 and 3/7 of the size of the two-dimensional code. I set it to the size of 1/3:
1 int maskWidth = Math.Min((int)(this.Width / 3), _maskWidth); //Final picture width 2 int maskHeight = Math.Min((int)(this.Height / 3), _maskHeight); //Final Picture Height 3 4 int maskLeft = (this.Width - maskWidth) / 2; //Picture location 5 int maskTop = (this.Height - maskHeight) / 2; //Picture location
In this way, when the Encode method is called to generate the two-dimensional code, the set pictures are automatically placed in the middle of the two-dimensional code.
Specific invocation method:
1 ErWeiMa.ErWeiMa er = new ErWeiMa.ErWeiMa(); 2 er.SetFillImage(Server.MapPath("~/t.jpg")); 3 this.img1.Src = er.Encode("The People's Republic of China");
The generated two-dimensional code is as follows:
Source code:
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 /// <summary> 22 /// Obtaining Two-Dimensional Code Image base64 String, which can be assigned directly to img Object src display 23 /// Default encoding UTF8,QRCodeEncoder The default value is Unicode 24 /// </summary> 25 /// <param name="content">Encoded content</param> 26 /// <returns>Two-dimensional code image base64 Character string</returns> 27 public string Encode(string content) 28 { 29 return this.Encode(content, encoding); 30 } 31 /// <summary> 32 /// Obtaining Two-Dimensional Code Image base64 String, which can be assigned directly to img Object src display 33 /// </summary> 34 /// <param name="content">Encoded content</param> 35 /// <param name="encoding">Coding type</param> 36 /// <returns>Two-dimensional code image base64 Character string</returns> 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 /// <summary> 74 /// Automatic acquisition based on encoding content QRCodeVersion value 75 /// </summary> 76 /// <param name="content"></param> 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 /// <summary> 89 /// each QRCodeVersion Value corresponds to the maximum number of bytes supported 90 /// </summary> 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 /// <summary> 93 /// QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H Every time QRCodeVersion Value corresponds to the maximum number of bytes supported 94 /// </summary> 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 /// <summary> 154 /// Setting 2-D Code Intermediate Picture 155 /// </summary> 156 /// <param name="fileName">Image file name, including path</param> 157 public void SetFillImage(string fileName) 158 { 159 SetFillImage(fileName, 100, 100); 160 } 161 /// <summary> 162 /// Setting 2-D Code Intermediate Picture 163 /// </summary> 164 /// <param name="fileName">Image file name, including path</param> 165 /// <param name="width">image width</param> 166 /// <param name="height">Picture height</param> 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 /// <summary> 176 /// Setting 2-D Code Intermediate Picture 177 /// </summary> 178 /// <param name="bitmap">Plot above IMAGE object</param> 179 public void SetFillImage(Image bitmap) 180 { 181 SetFillImage(bitmap, 100, 100); 182 } 183 /// <summary> 184 /// Setting 2-D Code Intermediate Picture 185 /// </summary> 186 /// <param name="bitmap">Plot above IMAGE object</param> 187 /// <param name="width">image width</param> 188 /// <param name="height">Picture height</param> 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 /// <summary> 197 /// Generated two-dimensional code width 198 /// </summary> 199 public int Width { get; set; } 200 /// <summary> 201 /// Generated two-dimensional code height 202 /// </summary> 203 public int Height { get; set; } 204 205 private int _maskWidth = 0; 206 private int _maskHeight = 0; 207 }
For the ThoughtWorks.QRCode.dll class library address, see my last note.