EAN13条形码由13位数字构成,其中第一位为前置码,最后一位为校验码。条码格式以下:
git
从左向右,取奇数位求和乘以1(不包含校验位),偶数位求和乘以3,将以上两步的结果求和再取和的个位数,最后再用10减这个个位数,就是最后一位校验码的值。算法
例如: 690123456789C(c为校验位)数组
① 计算奇数位的和:(6+0+2+4+6+8)*1=26;安全
② 计算偶数位的和:(9+1+3+5+7+9)*3=102;网络
③ 计算和:sum = 26+102=128;ide
④ 10-个位数:C=10-8=2。函数
从左向右,第2位到第7位(6个数字)为左侧字符。左侧字符采用两种编码方式:A方式或B方式,编码表以下:学习
而后根据前置码(第一位)肯定这6个字符的编码方式是A仍是B。编码
前置码决定的编码方式以下表:.net
例如:6901234567892的前置码为6,查上表,左侧6个数据的编码方式为ABBBAA。
右侧字符从第8个字符起到最后一位。均按照C方式编码。
2、生成条形码条形码只由和白区间表示,空白表示0,黑色表示1,因此先将十进制的数字字符根据编码表转化为二进制的形式,而后在绘制图像。
这里十进制转二进制不是按照运算法则转化,而是根据EAN-13的编码表进行转化。
public byte[] GetCodeChose(int prefix)
输入:prefix:前置码
输出:编码方式数组
该函数用来根据前置码获取编码方式。
byte[,][] code = new byte[3,10][];
或者写成定常数组也能够:
byte[,,,] code = new byte[3,10,7];
第一维存放编码方式;第二维存放十进制数字符号;第三维存放相应的二进制编码。
而后利用函数:
public byte[] GetCode(int type,int num)
输入: type:编码方式 ;num:十进制数字
输出:十进制字符的二进制表示。
EAN-13共113个模块(即113个条纹,包括左右两侧空白区),95个有效字符模块,而且条码的每一个模块(即一个条纹)是等宽的。
因此设置绘制函数以下:
public Image<Gray,byte> DrawCode(string text,string code, int minWidth,int height)
输入:text:前12个字符;code:二进制编码;条纹最小宽度;height:生成图像的高度
输出:条形码图像
其中,为了绘制起始位、分隔位以及终止位的不一样长度,将height - margin + height / 15做为起始位、分隔位以及终止位的长度。
注:起始符为101;分隔符为01010;终止符为101。能够在生成二进制编码时加上。
为了保证输入条码编号的有效性,这里作一个简单的验证。
简单点说就是利用黑白色对光的反射程度不一样,黑色吸取了大部分光波,白色返回大部分光波,因此根据返回的光波强就能够判断时扫描到的是黑色仍是白色区域,而后再转化为0或者1的数字信号便可。
上述方法是在有硬件条件下的识别方法,对于没有识别器的时候,咱们能够借助条码(或者二维码)识别库zbar(日本的)和zxing(美国的)来进行识别。或者直接根据像素点的值判断也可。
本次是利用zxing进行识别。
首先在NuGet中下载安装zxing.net,会自动引入zxing.dll。
而后实例化识别器:
BarcodeReader reader = new BarcodeReader();
获取结果集:
Result result = reader.Decode(bitmap)
获取识别文本:
string resText = result.Text;
这样一个简单的识别就完成了。
还能够设置字符编码:
ader.Options.CharacterSet = "UTF-8";4、源代码
完整项目地址(码云):https://gitee.com/xgpxg/BCGAR
5、截图