//
// ================================================ ==============
// Print the barcode
//
// Design: Chen Yan and 2011.03
// ================================================ ================
//
// Barcode128 has three different versions: A (numbers, upper-case letters, and control characters) B (numbers, size letters, and characters) C (double-digit numbers)
// BookProgramOnly B and C are processed. barcode128 consists of terminals, code bodies, code checks, and code tails,
//
Using system;
Using system. Collections. Generic;
Using system. LINQ;
Using system. text;
Using system. drawing;
Namespace cyh. General
{
/// <Summary>
/// Generate a bar code printing class
/// </Summary>
Public class barcode128
{
// The ASCII code area from 32 to 127, which consists of 3, 3 blank, and 11 units. The symbol contains the verification code.
Private string [] code128encoding = new string [] {
"11011001100", "11001101100", "11001100110", "10010011000", "10010001100", "10001001100", "10011001000", "10011000100", "10001100100", "11001001000 ",
"11001000100", "11000100100", "10110011100", "10011011100", "10011001110", "10111001100", "10011101100", "10011100110", "11001110010", "11001011100 ",
"11001001110", "11011100100", "11001110100", "11101101110", "11101001100", "11100101100", "11100100110", "11101100100", "11100110100", "11100110010 ",
"11011011000", "11011000110", "11000110110", "10100011000", "10001011000", "10001000110", "10110001000", "10001101000", "10001100010", "11010001000 ",
"11000101000", "11000100010", "10110111000", "10110001110", "10001101110", "10111011000", "10111000110", "10001110110", "11101110110", "11010001110 ",
"11000101110", "11011101000", "11011100010", "11011101110", "11101011000", "11101000110", "11100010110", "11101101000", "11101100010", "11100011010 ",
"11101111010", "11001000010", "11110001010", "10100110000", "10100001100", "10010110000", "10010000110", "10000101100", "10000100110", "10110010000 ",
"10110000100", "10011010000", "10011000010", "10000110100", "10000110010", "11000010010", "11001010000", "11110111010", "11000010100", "10001111010 ",
"10100111100", "10010111100", "10010011110", "10111100100", "10011110100", "10011110010", "11110100100", "11110010100", "11110010010", "11011011110 ",
"11011110110", "11110110110", "10101111000", "10100011110", "10001011110", "10111101000", "10111100010", "11110101000", "11110100010", "10111011110 ",
"10111101110", "11101011110", "11110101110", "11010000100", "11010010000", "11010011100"
};
Private const string code128stop = "11000111010", code128end = "11"; // fixed end code
Private Enum code128changemodes {codea = 101, codeb = 100, codec = 99}; // change
Private Enum code128startmodes {codeunset = 0, codea = 103, codeb = 104, codec = 105}; // all types of encoding Terminals
/// <Summary>
/// Draw the code128 code (in pixels)
/// </Summary>
Public int encodebarcode (string code, system. Drawing. Graphics g, int X, int y, int width, int height, bool showtext)
{
If (string. isnullorempty (CODE) new exception ("The Bar Code cannot be blank ");
List <int> encoded = codetoencoded (CODE); // 1. Split escape
Encoded. Add (checkdigitcode128 (encoded); // 2. Add the verification code
String encodestring = encodestring (encoded); // 3. Encoding
If (showtext) // calculates the text size. The font occupies 1/4 of the image size.
{
Font font = new system. Drawing. Font ("", height/5f, system. Drawing. fontstyle. Regular, graphicsunit. pixel, (byte) (0 )));
Sizef size = G. measurestring (Code, font );
Height = height-(INT) size. height;
G. drawstring (Code, Font, system. Drawing. Brushes. Black, X, Y + height );
Int W = drawbarcode (G, encodestring, X, Y, width, height); // 4. Draw
Return (INT) size. width> W? (INT) size. Width: W );
}
Else
Return drawbarcode (G, encodestring, X, Y, width, height); // 4. Draw
}
// 1. Detect and split the string and add it to the dock
Private list <int> codetoencoded (string code)
{
List <int> encoded = new list <int> ();
Int type = 0; // 2: Class B, Class C
For (INT I = 0; Code. length> 0; I ++)
{
Int K = isnumber (CODE );
If (k> = 4) // even consecutive numbers can give priority to Class C (in fact, it is not necessary to convert Class C, but the bar code will be shorter when class C is used)
{
If (type = 0) encoded. Add (INT) code128startmodes. codec); // join the dock
Else if (type! = 3) encoded. Add (INT) (code128changemodes. codec); // escape
Type = 3;
For (Int J = 0; j <K; j = J + 2) // a code body is composed of two digits.
{
Encoded. Add (int32.parse (code. substring (0, 2 )));
Code = code. substring (2 );
}
}
Else
{
If (INT) Code [0] <32 | (INT) Code [0]> 126) throw new exception ("the string must be a number or letter ");
If (type = 0) encoded. Add (INT) code128startmodes. codeb); // join the dock
Else if (type! = 2) encoded. Add (INT) (code128changemodes. codeb); // escape
Type = 2;
Encoded. Add (INT) Code [0]-32); // convert string to ASCII-32
Code = code. substring (1 );
}
}
Return encoded;
}
// 2. Check Code
Private int checkdigitcode128 (list <int> encoded)
{
Int check = encoded [0];
For (INT I = 1; I <encoded. Count; I ++)
Check = check + (encoded [I] * I );
Return (check % 103 );
}
// 2. encoding (corresponding to the code128encoding array)
private string encodestring (list encoded)
{< br> string encodedstring = "";
for (INT I = 0; I {< br> encodedstring + = code128encoding [encoded [I];
}< br> encodedstring + = code128stop + code128end; // Add the end Code
return encodedstring;
}
// 4. draw a bar code (returns the actual image width)
private int drawbarcode (system. drawing. graphics g, string encodestring, int X, int y, int width, int height)
{< br> int W = width/encodestring. length;
for (INT I = 0; I {< br> G. fillrectangle (encodestring [I] = '0 '? System. drawing. brushes. white: system. drawing. brushes. black, X, Y, W, height);
X + = W;
}< br> return w * (encodestring. length + 2);
}< br> // checks whether an even number is consecutive and returns the length of a consecutive number.
private int isnumber (string code)
{< br> int K = 0;
for (INT I = 0; I {< br> If (char. isnumber (code [I])
K ++;
else
break;
}< br> If (K % 2! = 0) k --;
return K;
}
/// <Summary>
/// Draw the code128 code to the image
/// </Summary>
Public Image encodebarcode (string code, int width, int height, bool showtext)
{
Bitmap image = new Bitmap (width, height );
Using (Graphics G = graphics. fromimage (image ))
{
G. Clear (color. White );
Int W = encodebarcode (Code, G, 0, 0, width, height, showtext );
Bitmap image2 = new Bitmap (W, height); // cut unnecessary spaces;
Using (Graphics g2 = graphics. fromimage (image2 ))
{
G2.drawimage (image, 0, 0 );
Return image2;
}
}
}
/// <Summary>
/// Draw the code128 code to the stream
/// </Summary>
Public byte [] encodebarcodebyte (string code, int width, int height, bool showtext)
{
Image image = encodebarcode (Code, width, height, showtext );
System. Io. memorystream MS = new system. Io. memorystream ();
Image. Save (MS, system. Drawing. imaging. imageformat. BMP );
Byte [] byteimage = Ms. toarray ();
Ms. Close ();
Image. Dispose ();
Return byteimage;
}
}
}