网文笔名:条码基础知识及开发简介
来源:百度文库 编辑:中财网 时间:2024/04/30 14:19:58
条码基础知识及开发简介
条码的基础知识
条码是指由一组规则排列的条、空及对应字符组成的标识,用以表示一定的商品信息的符号。
目前世界上常用的码制有ENA条形码、UPC条形码、25条形码、交叉25五条形码、库德巴条形码、39条形码和128条形码等,而商品上最常使用的就是EAN商品条形码。
条形码技术是在计算机技术与信息技术基础上发展起来的一门集编码、印刷、识别、数据采集和处理于一身的新兴技术,主要解决物品的自动识别问题。
条形码技术应用的主要特点:
1、 高速:键盘输入12位数字需要6秒,而用条形码扫描器输入只要0.2秒。
2、 准确:条形码的正确识读率达99.99%-----99.999%。
3、 成本低:自动识别技术中,条形码标签成本低,识读设备价格便宜。
4、 灵活:根据顾客或业务的需求,容易开发出 新产品,输入、输出设备种类多,操作简便。
条形码应用范围
1 商业领域
2 CODE
3 ITF
4 Codebar码多用在医疗、图书领域
5 生产企业工厂
条码分类
1、按码制分类
1) UPC码
1973年,美国率先在国内的商业系统中应用于UPC码之后加拿大也在商业系统中采用UPC码。UPC码是一种长度固定的连续型数字式码制,其字符集为数字0~9。它采用四种元素宽度,每个条或空是1、2、3或4倍单位元素宽度。IPC码有两种类型,即UPC-A码和UPC-E码。
2) EAN码
1977年,欧洲经济共同体各国按照UPC码的标准制定了欧洲物品编码EAN码,与UPC码兼容,而且两者具有相同的符号体系。EAN码的字符编号结构与UPC码相同,也是长度固定的、连续型的数字式码制,其字符集是数字0~9。它采用四种元素宽度,每个条或空是1、2、3或4倍单位元素宽度。EAN码有两种类型,即EAN
3)交叉
交叉
4)
5)库德巴码
库德巴码(Code Bar)出现于1972年,是一种长度可变的连续型自校验数字式码制。其字符集为数字0—9和6个特殊字符(-、:、/、。、+、¥),共16个字符。常用于仓库、血库和航空快递包裹中。
6)
7)
8)
9)其他码制
除上述码外,还有其他的码制,例如
2、按维数分类
1)普通的一维条码
普通的一维条码自本问世以来,很快得到了普及并广泛应用。但是由于一维条码的信息容量很小,如商品上的条码仅能容13位的阿拉伯数字,更多的描述商品的信息只能依赖数据库的支持,离开了预先建立的数据库,这种条码就变成了无源之水,无本之木,因而条码的应用范围受到了一定的限制。
2)二维条码
除具有普通条码的优点外,二维条码还具有信息容量大、可靠性高、保密防伪性强、易于制作、成本低等优点。
美国Symbol公司于1991年正式推出名为PDF417的二维条码,简称为PDF417条码,即“便携式数据文件”。FDF417条码是一种高密度、高信息含量的便携式数据文件,是实现证件及卡片等大容量、高可靠性信息自动存储、携带并可用机器自动识读的理想手段。
3)多维条码
进入20世纪80年代以来,人们围绕如何提高条形码符号的信息密度,进行了研究工作。多维条形码和集装箱条形码成为研究、以展与应用的方向。信息密度是描述条形码符号的一个重要参数据,即单位长度中可能编写的字母个数,通常记作:字母个数/cm。影响信息密度的主要因素是条、空结构和窄元系的宽度。
条码开发
1、 不同编码规则的条形码生成
public string bar_code(object str, int ch, int cw, int type_code)
{
//str:输入的字符串;ch:要显示条形码的高度;cw:要显示条形码的宽度;type_code:代码类型
string strTmp = str.ToString();
string code = strTmp;
// ToLower()将string转化成小写形式的副本,返回是使用指定区域的性的大小写规则。
strTmp = strTmp.ToLower();
int height = ch;
int width = cw;
//将传入的参数进行转化。
strTmp = strTmp.Replace("0", "_|_|__||_||_|"); ;
strTmp = strTmp.Replace("1", "_||_|__|_|_||");
strTmp = strTmp.Replace("2", "_|_||__|_|_||");
strTmp = strTmp.Replace("3", "_||_||__|_|_|");
strTmp = strTmp.Replace("4", "_|_|__||_|_||");
strTmp = strTmp.Replace("5", "_||_|__||_|_|");
strTmp = strTmp.Replace("7", "_|_|__|_||_||");
strTmp = strTmp.Replace("6", "_|_||__||_|_|");
strTmp = strTmp.Replace("8", "_||_|__|_||_|");
strTmp = strTmp.Replace("9", "_|_||__|_||_|");
strTmp = strTmp.Replace("a", "_||_|_|__|_||");
strTmp = strTmp.Replace("b", "_|_||_|__|_||");
strTmp = strTmp.Replace("c", "_||_||_|__|_|");
strTmp = strTmp.Replace("d", "_|_|_||__|_||");
strTmp = strTmp.Replace("e", "_||_|_||__|_|");
strTmp = strTmp.Replace("f", "_|_||_||__|_|");
strTmp = strTmp.Replace("g", "_|_|_|__||_||");
strTmp = strTmp.Replace("h", "_||_|_|__||_|");
strTmp = strTmp.Replace("i", "_|_||_|__||_|");
strTmp = strTmp.Replace("j", "_|_|_||__||_|");
strTmp = strTmp.Replace("k", "_||_|_|_|__||");
strTmp = strTmp.Replace("l", "_|_||_|_|__||");
strTmp = strTmp.Replace("m", "_||_||_|_|__|");
strTmp = strTmp.Replace("n", "_|_|_||_|__||");
strTmp = strTmp.Replace("o", "_||_|_||_|__|");
strTmp = strTmp.Replace("p", "_|_||_||_|__|");
strTmp = strTmp.Replace("r", "_||_|_|_||__|");
strTmp = strTmp.Replace("q", "_|_|_|_||__||");
strTmp = strTmp.Replace("s", "_|_||_|_||__|");
strTmp = strTmp.Replace("t", "_|_|_||_||__|");
strTmp = strTmp.Replace("u", "_||__|_|_|_||");
strTmp = strTmp.Replace("v", "_|__||_|_|_||");
strTmp = strTmp.Replace("w", "_||__||_|_|_|");
strTmp = strTmp.Replace("x", "_|__|_||_|_||");
strTmp = strTmp.Replace("y", "_||__|_||_|_|");
strTmp = strTmp.Replace("z", "_|__||_||_|_|");
strTmp = strTmp.Replace("-", "_|__|_|_||_||");
strTmp = strTmp.Replace("*", "_|__|_||_||_|");
strTmp = strTmp.Replace("/", "_|__|__|_|__|");
strTmp = strTmp.Replace("%", "_|_|__|__|__|");
strTmp = strTmp.Replace("+", "_|__|_|__|__|");
strTmp = strTmp.Replace(".", "_||__|_|_||_|");
strTmp = strTmp.Replace("_", "");
strTmp = strTmp.Replace("|", "");
if (type_code == 1)
{
return strTmp + "
" + code;
}
else
{
return strTmp;
}
}
2、 条形码打印
条码打印机分两种:(1)有驱动条码打印机(2)无驱动条码打印机。针对于不同类型的打印机有不同打印方式
(一) 有驱动条码打印机
针对于有驱条码打印机,可以直接用windows的API,指令格式是一样的只需要知道安装后的打印机名称即可。
p_PrintName 为打印机名称
public static void WinApiPrintByte(string p_PrintName, byte[] p_Byte)
{
if (p_PrintName != null && p_PrintName.Length > 0)
{
IntPtr _PrintHandle;
IntPtr _JobHandle = Marshal.AllocHGlobal(100);
if (Win32API.OpenPrinter(p_PrintName, out _PrintHandle, IntPtr.Zero))
{
ADDJOB_INFO_1 _JobInfo = new ADDJOB_INFO_1();
int _Size;
AddJob(_PrintHandle, 1, _JobHandle, 100, out _Size);
_JobInfo = (ADDJOB_INFO_1)Marshal.PtrToStructure(_JobHandle, typeof(ADDJOB_INFO_1));
System.IO.File.WriteAllBytes(p_PrintName, p_Byte);
ScheduleJob(_PrintHandle, _JobInfo.JobID);
ClosePrinter(_PrintHandle);
Marshal.FreeHGlobal(_JobHandle);
}
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct ADDJOB_INFO_1
{
[MarshalAs(UnmanagedType.LPTStr)]
public string lpPath;
public Int32 JobID;
}
[DllImport("winspool.drv", CharSet = CharSet.Auto)]
public static extern bool AddJob(IntPtr ptrPrinter, Int32 iLevel, IntPtr ptrJob, Int32 iSize, out Int32 iCpSize);
[DllImport("winspool.drv", CharSet = CharSet.Auto)]
public static extern bool ScheduleJob(IntPtr ptrPrinter, Int32 JobID);
[DllImport("winspool.drv", CharSet = CharSet.Auto)]
public static extern bool ClosePrinter(IntPtr ptrPrinter);
(二) 无驱动条码打印机
无驱打印机主要有LPT打印机和IP打印机,该种打印机是通过ZPL指令直接给端口发指令即可
3、 条形码的读取
条形码读取的方式主要有两种:
1) 键盘口或USB口
该种接口的条码读写器,如同在键盘上按下数字键一样,基本不需任何编程和处理
2) 其他接口
如果你使用的是其它接口的话,可能你就要为该设备编写通讯代码了。
static SerialPort _serialPort;
public static void Main()
{
string name;
string message;
StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
Thread readThread = new Thread(Read);
// Create a new SerialPort object with default settings.
_serialPort = new SerialPort();
// Allow the user to set the appropriate properties.
_serialPort.PortName = SetPortName(_serialPort.PortName);
_serialPort.BaudRate = SetPortBaudRate(_serialPort.BaudRate);
_serialPort.Parity = SetPortParity(_serialPort.Parity);
_serialPort.DataBits = SetPortDataBits(_serialPort.DataBits);
_serialPort.StopBits = SetPortStopBits(_serialPort.StopBits);
_serialPort.Handshake = SetPortHandshake(_serialPort.Handshake);
// Set the read/write timeouts
_serialPort.ReadTimeout = 500;
_serialPort.WriteTimeout = 500;
_serialPort.Open();
_continue = true;
readThread.Start();
Console.Write("Name: ");
name = Console.ReadLine();
Console.WriteLine("Type QUIT to exit");
while (_continue)
{
message = Console.ReadLine();
if (stringComparer.Equals("quit", message))
{
_continue = false;
}
else
{
_serialPort.WriteLine(
String.Format("<{0}>: {1}", name, message));
}
}
readThread.Join();
_serialPort.Close();
}
public static void Read()
{
while (_continue)
{
try
{
string message = _serialPort.ReadLine();
Console.WriteLine(message);
}
catch (TimeoutException) { }
}
}