Code128 條碼產生

來源:互聯網
上載者:User

//
// =================================================
//   條碼列印
//   
//    設計: 陳炎和 2011.03
//==================================================
//
//BarCode128有三種不同的版本:A(數字、大寫字母、控制字元)B(數字、大小字母、字元)C(雙位元字)
//本程式只處理B、C,BarCode128由碼頭、碼身、碼檢、碼尾組成,
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;


namespace cyh.General
{
    /// <summary>
    /// 產生條碼列印類
    /// </summary>
    public class BarCode128
    {
        //ASCII從32到127對應的條碼區,由3個條、3個空、共11個單元構成,符號內含校正碼
        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";      //固定碼尾
        private enum Code128ChangeModes { CodeA = 101, CodeB = 100, CodeC = 99 }; //變更
        private enum Code128StartModes { CodeUnset = 0, CodeA = 103, CodeB = 104, CodeC = 105 };//各類編碼的碼頭

        /// <summary>
        /// 繪製Code128碼(以像素為單位)
        /// </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("條碼不可為空");
            List<int> encoded = CodetoEncoded(code);            //1.拆分轉義
            encoded.Add(CheckDigitCode128(encoded));            //2.加入校正碼
            string encodestring = EncodeString(encoded);        //3.編碼
           
            if (showText) //計算文本的大小,字型占映像的1/4高
            {
                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.繪製
                return ((int)size.Width > w ? (int)size.Width : w);
            }
            else
                return DrawBarCode(g, encodestring, x, y, width, height); //4.繪製
        }
       
        //1.檢測並將字串拆分並加入碼頭
        private List<int> CodetoEncoded(string code)
        {
            List<int> encoded = new List<int>();
            int type = 0;//2:B類,3:C類
            for (int i = 0; code.Length > 0; i++)
            {
                int k = isNumber(code);
                if (k >= 4)   //連續偶個數字可優先使用C類(其實並不定要轉C類,但能用C類時條碼會更短)
                {
                    if (type == 0) encoded.Add((int)Code128StartModes.CodeC);   //加入碼頭
                    else if (type != 3) encoded.Add((int)(Code128ChangeModes.CodeC)); //轉義
                    type = 3;
                    for (int j = 0; j < k; j = j + 2) //兩位元字合為一個碼身
                    {
                        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("字串必須是數字或字母");
                    if (type == 0) encoded.Add((int)Code128StartModes.CodeB);   //加入碼頭
                    else if (type != 2) encoded.Add((int)(Code128ChangeModes.CodeB)); //轉義
                    type = 2;
                    encoded.Add((int)code[0] - 32);//字串轉為ASCII-32
                    code = code.Substring(1);
                }
            }
            return encoded;
        }
        //2.校正碼
        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.編碼(對應Code128Encoding數組)
        private string EncodeString(List<int> encoded)
        {
            string encodedString = "";
            for (int i = 0; i < encoded.Count; i++)
            {
                encodedString += Code128Encoding[encoded[i]];
            }
            encodedString += Code128Stop + Code128End; // 加入結束碼
            return encodedString;
        }

        //4.繪製條碼(返回實際映像寬度)
        private int DrawBarCode(System.Drawing.Graphics g, string encodeString, int x, int y, int width, int height)
        {
            int w = width / encodeString.Length;
            for (int i = 0; i < encodeString.Length; i++)
            {
                g.FillRectangle(encodeString[i] == '0' ? System.Drawing.Brushes.White : System.Drawing.Brushes.Black, x, y, w, height);
                x += w;
            }
            return w * (encodeString.Length+2);
        }
        //檢測是否連續偶個數字,返回連續數位長度
        private int isNumber(string code)
        {
            int k = 0;
            for (int i = 0; i < code.Length; i++)
            {
                if (char.IsNumber(code[i]))
                    k++;
                else
                    break;
            }
            if (k % 2 != 0) k--;
            return k;
        }

        /// <summary>
        /// 繪製Code128碼到圖片
        /// </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); //剪下多餘的空白;
                using (Graphics g2 = Graphics.FromImage(image2))
                {
                    g2.DrawImage(image, 0, 0);
                    return image2;
                }

            }

        }
        /// <summary>
        /// 繪製Code128碼到流
        /// </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;

        }
    }
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.