Bar code generation and recognition
EAN-13条形码的生成与识别
[TOC]
EAN13条形码由13位数字构成,其中第一位为前置码,最后一位为校验码。条码格式如下:
图1.1 条形码格式
图1.2 条形码区域划分
从左向右,取奇数位求和乘以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;
④ 10-个位数:C=10-8=2。
从左向右,第2位到第7位(6个数字)为左侧字符。左侧字符采用两种编码方式:A方式或B方式,编码表如下:
图1.3 左侧字符编码
然后根据前置码(第一位)确定这6个字符的编码方式是A还是B。
前置码决定的编码方式如下表:
图1.3 编码方式
例如:6901234567892的前置码为6,查上表,左侧6个数据的编码方式为ABBBAA。
右侧字符从第8个字符起到最后一位。均按照C方式编码。
条形码只由和白区间表示,空白表示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:十进制数字
输出:十进制字符的二进制表示。
##2 绘制条形码
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";
完整项目地址(码云):https://gitee.com/xgpxg/BCGAR
图5.1 条码生成截图
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。