Two-dimensional code generation 2

Keywords: ASP.NET encoding QRCode Attribute

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.

Posted by PureDrive on Mon, 08 Apr 2019 00:24:31 -0700