Code128.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Text;
  5. namespace UAS_Web.tool
  6. {
  7. public class Code128
  8. {
  9. //ASCII从32到127对应的条码区,由3个条、3个空、共11个单元构成,符号内含校验码
  10. private string[] Code128Encoding = new string[] {
  11. "11011001100", "11001101100", "11001100110", "10010011000", "10010001100", "10001001100", "10011001000", "10011000100", "10001100100", "11001001000",
  12. "11001000100", "11000100100", "10110011100", "10011011100", "10011001110", "10111001100", "10011101100", "10011100110", "11001110010", "11001011100",
  13. "11001001110", "11011100100", "11001110100", "11101101110", "11101001100", "11100101100", "11100100110", "11101100100", "11100110100", "11100110010",
  14. "11011011000", "11011000110", "11000110110", "10100011000", "10001011000", "10001000110", "10110001000", "10001101000", "10001100010", "11010001000",
  15. "11000101000", "11000100010", "10110111000", "10110001110", "10001101110", "10111011000", "10111000110", "10001110110", "11101110110", "11010001110",
  16. "11000101110", "11011101000", "11011100010", "11011101110", "11101011000", "11101000110", "11100010110", "11101101000", "11101100010", "11100011010",
  17. "11101111010", "11001000010", "11110001010", "10100110000", "10100001100", "10010110000", "10010000110", "10000101100", "10000100110", "10110010000",
  18. "10110000100", "10011010000", "10011000010", "10000110100", "10000110010", "11000010010", "11001010000", "11110111010", "11000010100", "10001111010",
  19. "10100111100", "10010111100", "10010011110", "10111100100", "10011110100", "10011110010", "11110100100", "11110010100", "11110010010", "11011011110",
  20. "11011110110", "11110110110", "10101111000", "10100011110", "10001011110", "10111101000", "10111100010", "11110101000", "11110100010", "10111011110",
  21. "10111101110", "11101011110", "11110101110", "11010000100", "11010010000", "11010011100"
  22. };
  23. private const string Code128Stop = "11000111010", Code128End = "11"; //固定码尾
  24. private enum Code128ChangeModes { CodeA = 101, CodeB = 100, CodeC = 99 }; //变更
  25. private enum Code128StartModes { CodeUnset = 0, CodeA = 103, CodeB = 104, CodeC = 105 };//各类编码的码头
  26. /// <summary>
  27. /// 绘制Code128码(以像素为单位)
  28. /// </summary>
  29. public int EncodeBarcode(string code, System.Drawing.Graphics g, int x, int y, int width, int height, bool showText)
  30. {
  31. if (string.IsNullOrEmpty(code)) new Exception("条码不能为空");
  32. List<int> encoded = CodetoEncoded(code); //1.拆分转义
  33. encoded.Add(CheckDigitCode128(encoded)); //2.加入校验码
  34. string encodestring = EncodeString(encoded); //3.编码
  35. if (showText) //计算文本的大小,字体占图像的1/4高
  36. {
  37. Font font = new System.Drawing.Font("宋体", height / 7F, System.Drawing.FontStyle.Regular, GraphicsUnit.Pixel, ((byte)(0)));
  38. SizeF size = g.MeasureString(code, font);
  39. height = height - (int)size.Height;
  40. g.DrawString(code, font, System.Drawing.Brushes.Black, x+11, y + height);
  41. int w = DrawBarCode(g, encodestring, x, y, width, height); //4.绘制
  42. return ((int)size.Width > w ? (int)size.Width : w);
  43. }
  44. else
  45. return DrawBarCode(g, encodestring, x, y, width, height); //4.绘制
  46. }
  47. //1.检测并将字符串拆分并加入码头
  48. private List<int> CodetoEncoded(string code)
  49. {
  50. List<int> encoded = new List<int>();
  51. int type = 0;//2:B类,3:C类
  52. for (int i = 0; code.Length > 0; i++)
  53. {
  54. int k = isNumber(code);
  55. if (k >= 4) //连续偶个数字可优先使用C类(其实并不定要转C类,但能用C类时条码会更短)
  56. {
  57. if (type == 0) encoded.Add((int)Code128StartModes.CodeC); //加入码头
  58. else if (type != 3) encoded.Add((int)(Code128ChangeModes.CodeC)); //转义
  59. type = 3;
  60. for (int j = 0; j < k; j = j + 2) //两位数字合为一个码身
  61. {
  62. encoded.Add(Int32.Parse(code.Substring(0, 2)));
  63. code = code.Substring(2);
  64. }
  65. }
  66. else
  67. {
  68. if ((int)code[0] < 32 || (int)code[0] > 126) throw new Exception("字符串必须是数字或字母");
  69. if (type == 0) encoded.Add((int)Code128StartModes.CodeB); //加入码头
  70. else if (type != 2) encoded.Add((int)(Code128ChangeModes.CodeB)); //转义
  71. type = 2;
  72. encoded.Add((int)code[0] - 32);//字符串转为ASCII-32
  73. code = code.Substring(1);
  74. }
  75. }
  76. return encoded;
  77. }
  78. //2.校验码
  79. private int CheckDigitCode128(List<int> encoded)
  80. {
  81. int check = encoded[0];
  82. for (int i = 1; i < encoded.Count; i++)
  83. check = check + (encoded[i] * i);
  84. return (check % 103);
  85. }
  86. //2.编码(对应Code128Encoding数组)
  87. private string EncodeString(List<int> encoded)
  88. {
  89. string encodedString = "";
  90. for (int i = 0; i < encoded.Count; i++)
  91. {
  92. encodedString += Code128Encoding[encoded[i]];
  93. }
  94. encodedString += Code128Stop + Code128End; // 加入结束码
  95. return encodedString;
  96. }
  97. //4.绘制条码(返回实际图像宽度)
  98. private int DrawBarCode(System.Drawing.Graphics g, string encodeString, int x, int y, int width, int height)
  99. {
  100. //int w = width / encodeString.Length;
  101. int w = 1;
  102. for (int i = 0; i < encodeString.Length; i++)
  103. {
  104. g.FillRectangle(encodeString[i] == '0' ? System.Drawing.Brushes.White : System.Drawing.Brushes.Black, x, y, w, height);
  105. x += w;
  106. }
  107. return w * (encodeString.Length + 2);
  108. }
  109. //检测是否连续偶个数字,返回连续数字的长度
  110. private int isNumber(string code)
  111. {
  112. int k = 0;
  113. for (int i = 0; i < code.Length; i++)
  114. {
  115. if (char.IsNumber(code[i]))
  116. k++;
  117. else
  118. break;
  119. }
  120. if (k % 2 != 0) k--;
  121. return k;
  122. }
  123. /// <summary>
  124. /// 绘制Code128码到图片
  125. /// </summary>
  126. public Image EncodeBarcode(string code, int width, int height, bool showText)
  127. {
  128. Bitmap image = new Bitmap(width, height);
  129. using (Graphics g = Graphics.FromImage(image))
  130. {
  131. g.Clear(Color.White);
  132. int w = EncodeBarcode(code, g, 15, 0, width, height, showText);
  133. Bitmap image2 = new Bitmap(w+15, height); //剪切多余的空白;
  134. using (Graphics g2 = Graphics.FromImage(image2))
  135. {
  136. g2.DrawImage(image, 0, 0);
  137. return image2;
  138. }
  139. }
  140. }
  141. /// <summary>
  142. /// 绘制Code128码到流
  143. /// </summary>
  144. public byte[] EncodeBarcodeByte(string code, int width, int height, bool showText)
  145. {
  146. Image image = EncodeBarcode(code, width, height, showText);
  147. System.IO.MemoryStream ms = new System.IO.MemoryStream();
  148. image.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
  149. byte[] byteImage = ms.ToArray();
  150. ms.Close();
  151. image.Dispose();
  152. return byteImage;
  153. }
  154. }
  155. }