有一段用VFP写的生成条形码的源程序,如果你会使用VFP并将其编译成COM组件,估计应该可以直接使用生成图片。
代码作者:行者孙
代码出处:http://www.chinavfp.com/dispbbs.asp?boardid=26&replyid=69008&id=15078&skin=0&page=1&star=1
EAN码是国际物品编码协会制定的一种商品用条码,通用于全世界。EAN码符号有标准版(EAN-13)和缩短版(EAN-8)两种,我国的通用商品条码与其等效。我们日常购买的商品包装上所印的条码一般就是EAN码。我这里给出的是EAN-13的算法代码,大家如果需要EAN-8条码可以自行修改下。
本算法属本论坛首发,请大家转载注明出处!谢谢!
* 函 数 名:EAN13()
* 功 能:根据条EAN-13码符号字符串生成条码位图
* 参 数:BM 字符型(12位EAN-13码符号字符串 如:'690102818039')
* 返 回 值:生成的条码位图的文件名
* 运行环境:WIN95以上版本。Visual FoxPro 6.0,7.0,8.0,9.0
* 算法制作:行者孙(QQ:310727570)-VFP应用程式算法群(12787940)
* 说 明:转载请保留出处!
Function EAN13(BM As String )
Private BM
Dimension EAN_code[10,3]
EAN_code[1,1]='00000011110011'
EAN_code[1,2]='00110000111111'
EAN_code[1,3]='11111100001100'
EAN_code[2,1]='00001111000011'
EAN_code[2,2]='00111100001111'
EAN_code[2,3]='11110000111100'
EAN_code[3,1]='00001100001111'
EAN_code[3,2]='00001111001111'
EAN_code[3,3]='11110011110000'
EAN_code[4,1]='00111111001100'
EAN_code[4,2]='00001111110011'
EAN_code[4,3]='11000000001100'
EAN_code[5,1]='00110000001111'
EAN_code[5,2]='00001111110011'
EAN_code[5,3]='11001111110000'
EAN_code[6,1]='00111100000011'
EAN_code[6,2]='00111111000011'
EAN_code[6,3]='11000011111100'
EAN_code[7,1]='00110011111111'
EAN_code[7,2]='00000011001111'
EAN_code[7,3]='11001100000000'
EAN_code[8,1]='00111111001111'
EAN_code[8,2]='00001100000011'
EAN_code[8,3]='11000000110000'
EAN_code[9,1]='00111100111111'
EAN_code[9,2]='00000011000011'
EAN_code[9,3]='11000011000000'
EAN_code[10,1]='00000011001111'
EAN_code[10,2]='00001100111111'
EAN_code[10,3]='11111100110000'
Dimension EAN_left[10]
EAN_left[1]='111111'
EAN_left[2]='112122'
EAN_left[3]='112212'
EAN_left[4]='112221'
EAN_left[5]='121122'
EAN_left[6]='122112'
EAN_left[7]='122211'
EAN_left[8]='121212'
EAN_left[9]='121221'
EAN_left[10]='122121'
Dimension EAN_mode[8]
Store '' To EAN_mode
If Len(Alltrim(BM))<>12 .And. Val(BM)>0
Messagebox('EAN-13编码长度不规范',268,'信息提示')
Return ''
Else
EAN_mode[1]='000000000000000000'
EAN_mode[2]='110011'
For i=0 To 9
If Val(Substr(BM,1,1))=i
For ii=1 To 6
BMZ=Val(Substr(BM,ii+1,1))
MODE=Val(Substr(EAN_left[i+1],ii,1))
EAN_mode[3]=EAN_mode[3]+EAN_code[BMZ+1,MODE]
Endf
Endi
Endf
EAN_mode[4]='0011001100'
For i=1 To 5
BMZ=Val(Substr(BM,i+7,1))
EAN_mode[5]=EAN_mode[5]+EAN_code[BMZ+1,3]
Endf
JY_A=0
JY_B=0
For i=1 To 12
If i%2=0
JY_A=JY_A+Val(Substr(BM,i,1))
Else
JY_B=JY_B+Val(Substr(BM,i,1))
Endif
Endf
JYM=10-(JY_A*3+JY_B)%10
If JYM=10
JYM=1
Endi
EAN_mode[6]=EAN_code[JYM+1,3]
EAN_mode[7]='110011'
EAN_mode[8]='000000000000000000'
EAN_code=EAN_mode[1]+EAN_mode[2]+EAN_mode[3]++EAN_mode[4]+EAN_mode[5]+EAN_mode[6]+EAN_mode[7]+EAN_mode[8]
Dimension BMP[4]
BMP[4]=90
BMP[3]=224
BMP[2]=Int((BMP[3]*3+3)/4)*4*BMP[4]+54
BMP[1]=BMP[2]-54
Dimension BMP_T[4]
For i=1 To 4
k1='0x'+Subs(Righ(Tran(BMP[i],"@0"),8),7,2)
k2='0x'+Subs(Righ(Tran(BMP[i],"@0"),8),5,2)
k3='0x'+Subs(Righ(Tran(BMP[i],"@0"),8),3,2)
k4='0x'+Subs(Righ(Tran(BMP[i],"@0"),8),1,2)
BMP_T[i]=Chr(&k1)+Chr(&k2)+Chr(&k3)+Chr(&k4)
Endf
st1='BM'+BMP_T[2]+Chr(0)+Chr(0)+Chr(0)+Chr(0)+Chr(54)+Chr(0)+Chr(0)+Chr(0);
+Chr(40)+Chr(0)+Chr(0)+Chr(0)+BMP_T[3]+BMP_T[4]+Chr(1)+Chr(0)+Chr(24)+Chr(0)+Chr(0)+Chr(0)+Chr(0)+Chr(0)+BMP_T[1]+Chrt(Spac(16),' ',Chr(0))
st2=Chrt(Spac(224*10*3),' ',Chr(255))
st3=''
For i=11 To 70
For k1=1 To 224
If Substr(EAN_code,k1,1)=='1'
st3=st3+Chr(0)+Chr(0)+Chr(0)
Else
st3=st3+Chr(255)+Chr(255)+Chr(255)
Endi
Endf
Endf
Pb=Chr(0)+Chr(0)+Chr(0)
Pw=Chr(255)+Chr(255)+Chr(255)
st4=Chrt(Spac(18*3),' ',Chr(255))+Pb+Pb+Pw+Pw+Pb+Pb+Chrt(Spac(84*3),' ',Chr(255))+Pw+Pw+Pb+Pb+Pw+Pw+Pb+Pb+Pw+Pw+Chrt(Spac(84*3),' ',Chr(255))+Pb+Pb+Pw+Pw+Pb+Pb+Chrt(Spac(16*3),' ',Chr(255))
st4=st4+st4
Dimension T_D[11]
T_D[1]='11111000111111111100000111111110111100111111101111101111111011111011111110111110111111101111101111'+;
'11101111101111111011111011111110111110111111101111101111111011110011111111000001111111111000111111'
T_D[2]='11111110111111111111001111111111100011111111100000111111111011101111111111111011111111111110111111'+;
'11111110111111111111101111111111111011111111111110111111111111101111111111111011111111111110111111'
T_D[3]='11111000111111111000000111111110111110111111101111101111111111111011111111111110111111111111011111'+;
'11111110011111111111001111111111100111111111110011111111111001111111111110000000111111000000001111'
T_D[4]='11111000111111111100000111111110011100111111101111101111111111110111111111110011111111111100011111'+;
'11111111101111111111111011111111111110111111101111101111111011110011111111000001111111111000111111'
T_D[5]='11111111011111111111100111111111111001111111111100011111111110110111111111011101111111110111011111'+;
'11101111011111110111110111111100000000011111000000000111111111110111111111111101111111111111011111'
T_D[6]='11110000001111111100000011111111011111111111110111111111111000001111111110000001111111101111101111'+;
'11111111101111111111111011111111111110111111101111101111111011110011111111000001111111111000111111'
T_D[7]='11111000111111111100000111111110011110111111101111111111111011001111111110000001111111100111001111'+;
'11101111101111111011111011111110111110111111101111101111111001111011111111000001111111111000111111'
T_D[8]='11000000001111110000000011111111111100111111111111011111111111101111111111111011111111111101111111'+;
'11111101111111111110011111111111101111111111111011111111111110111111111111101111111111110011111111'
T_D[9]='11111000111111111100000111111110011100111111101111101111111011111011111110011100111111110000011111'+;
'11110000011111111011111011111110111110111111101111101111111011111011111110000001111111111000111111'
T_D[10]='11111000111111111100000111111110111100111111101111101111111011111011111110111110111111101111101111'+;
'11101111001111111100000011111111100110111111111111101111111011110111111110000001111111111001111111'
T_D[11]='11111111111111111111111111111111111111111111111111001111111111000011111111000001111111100111111111'+;
'11100111111111111100000111111111110000111111111111001111111111111111111111111111111111111111111111'
Dimension td[14]
Store '' To td
For i=1 To 14
For k1=1 To 13
zh=Val(Substr(BM+Alltrim(Str(JYM)),k1,1))+1
td[i]=td[i]+Substr(T_D[zh],14*i-13,14)
Endf
td[i]=td[i]+Substr(T_D[11],14*i-13,14)
Endf
For i=1 To 7
td[i]='11'+Subs(td[i],1,14)+'11'+'001100'+Subs(td[i],15,84)+'1100110011'+Subs(td[i],99,84)+'001100'+Subs(td[i],183,14)+'11'
Endf
For i=8 To 14
td[i]='11'+Subs(td[i],1,14)+'11'+'111111'+Subs(td[i],15,84)+'1111111111'+Subs(td[i],99,84)+'111111'+Subs(td[i],183,14)+'11'
Endf
For i=1 To 14
td[i]=Strtran(td[i],'1',Chr(255)+Chr(255)+Chr(255))
td[i]=Strtran(td[i],'0',Chr(0)+Chr(0)+Chr(0))
Endf
st5=Chrt(Spac(224*4*3),' ',Chr(255))
h=Fcreate(BM+Alltrim(Str(JYM))+'.bmp')
=Fwrite(h,st1)
=Fwrite(h,st5)
For i=14 To 1 Step -1
=Fwrite(h,td[i])
Endf
=Fwrite(h,st4)
=Fwrite(h,st3)
=Fwrite(h,st2)
Fclose(h)
Return BM+Alltrim(Str(JYM))+'.bmp'
Endif
Endfunc
如:thisform.image1.picture=EAN13('6901028039')
作者补充内容:
A、条码中的‘<’是标准版的EAN-13中的,现在好多都把这个省略掉了,不过有和没有不影响条码机器的检测的,自己也可以修改上面的代码把它去掉,我做的是通用的EAN13算法,所以还是把它加上了!
B、EAN-13条码是由12位信息+1位校验码组成,前12位才是条码的编号,最后的第13位是根据前面12位的信息码计算出来的校验码,是算法自动生成的。
C、其他问题的解答:
1、能否自定义图片尺寸?
可以的,这个我想看过我写的那片《VFP下位图的结构及低级操作》那篇文章后基本大家都能改成可以自定义尺寸的代码了!
2、EAN-13的长度
顾名思义,EAN-13的长度就是13位,前12位是自定义位,最后一位是校验位,代码中是自动帮你算出校验位的,所以你只要输入前12为的自定义位就可以了。
3、关于生成的图片中有个‘<’的问题
标准的EAN条码中(应该说大部分条码)按规定是要有一个结束符的,这个结束符就是<。但在实际应用中没有这个结束符也可以正确扫描的,大部分专用软件为了节省代码或者为了更通俗性就将这个结束符取消了,如果想取消大家可以在代码里找到往位图里写入<符号的那部分取消掉。
4、关于条码的宽度
每种条码的宽度比例都是有严格规定的,这个规定一般国家商品编码管理部门都有相应的硬性规定的,因为当时给我手上也没有国家部门颁发的相关文件,所以是在国外的一个网站上找的,也可能和标准的编码过则有不同的地方,这个修改比较方便,只要你有准确的编码规则通过修改程序里代码规则数组里的值就可以了。说句心里话,条码是一个国际性的标准,既然是标准就应该广而告之,但在国内的网站上根本就找不到什么有用的东西,除非你花钱买!
5、关于图像显示问题
VFP6前image控件只可以通过pictuer属性来调用已经保存在硬盘上的图片,之后VFP的iamge控件有了个新的属性pictuervalue,这个属性在一些显示图像的问题上实用价值非常大,它可以直接通过图像信息的二进制流来显示图片,这对于一个需要先绘制图片再显示图片的程序在运行速度上简直是飞跃式的提高,所以我写的这段代码大家也可以先不用保存成图片而是在内存中直接操作数据流,需要保存的时候用strtofile()就可以了。
另外如果大家有其他条码的相关资料可以发给我,如果全的话我可以给大家写一个通用的商业条码函数以方便广大狐友!