C#生成Code39条形码而非条形码字体的方法
由于Code39编译简单、能够对任意长度的数据进行编码、支持设备比较广泛所以被广泛的采用,下面通过文字说明和代码分析给大家介绍下C#生成Code39条形码而非条形码字体的方法。
能够对任意长度的数据进行编码。其局限在于印刷品的长度和条码阅读器的识别范围。
支持设备广泛。目前几乎所有的条形码阅读设备都能阅读Code39码,打印机也是同样情况。
编制简单。简单的开发技术就能快速生成相应的编码图像。
一般Code39码由5条线和分开它们的4条缝隙共9个元素构成。线和缝隙有宽窄之分,而且无论线还是缝隙仅有3个比其他的元素要宽一定比例。39码因此得名
Code39条形码规则
1、每五条线表示一个字符;
2、粗线表示1,细线表示0;
3、线条间的间隙宽的表示1,窄的表示0;
4、五条线加上它们之间的四条间隙就是九位二进制编码,而且这九位中必定有三位是1,所以称为39码;
5、条形码的首尾各一个*标识开始和结束。
Code39只接受如下43个有效输入字符:
1、26个大写字母(A-Z),
2、十个数字(0-9),
3、连接号(-),句号(.),空格,美圆符号($),斜扛(/),加号(+)以及百分号(%)。
4、其余的输入将被忽略。
5、code39通常情况下不需要校验码。但是对於精确度要求高的应用,需要在code39条形码後面增加一个校验码。
条形码的生成网上也有很多库文件,做的特别好的都是商业授权。一维码二维码在.net开源项目中的生成读取比较知名的有:Zxing.net(http://zxingnet.codeplex.com/>http://zxingnet.codeplex.com/<\/a>)、BarcodeLib等
但有些时候开源软件所实现的并不满足当下的需求,所以还要做一些其他尝试。效果如下图:
代码分享:
///<summary> ///Code39一维码生成类 ///http://www.cnblogs.com/bluescreen/p/4689351.html ///</summary> publicclassCSharpCode39 { #region数据码 privatebyte[,]c39_bp=newbyte[,]{ {0x30,0x30,0x30,0x30,0x31,0x31,0x30,0x31,0x30,0x30},{0x31,0x31,0x30,0x30,0x31,0x30,0x30,0x30,0x30,0x31},{0x32,0x30,0x30,0x31,0x31,0x30,0x30,0x30,0x30,0x31},{0x33,0x31,0x30,0x31,0x31,0x30,0x30,0x30,0x30,0x30},{0x34,0x30,0x30,0x30,0x31,0x31,0x30,0x30,0x30,0x31},{0x35,0x31,0x30,0x30,0x31,0x31,0x30,0x30,0x30,0x30},{0x36,0x30,0x30,0x31,0x31,0x31,0x30,0x30,0x30,0x30},{0x37,0x30,0x30,0x30,0x31,0x30,0x30,0x31,0x30,0x31},{0x38,0x31,0x30,0x30,0x31,0x30,0x30,0x31,0x30,0x30},{0x39,0x30,0x30,0x31,0x31,0x30,0x30,0x31,0x30,0x30},{0x41,0x31,0x30,0x30,0x30,0x30,0x31,0x30,0x30,0x31},{0x42,0x30,0x30,0x31,0x30,0x30,0x31,0x30,0x30,0x31},{0x43,0x31,0x30,0x31,0x30,0x30,0x31,0x30,0x30,0x30},{0x44,0x30,0x30,0x30,0x30,0x31,0x31,0x30,0x30,0x31},{0x45,0x31,0x30,0x30,0x30,0x31,0x31,0x30,0x30,0x30},{70,0x30,0x30,0x31,0x30,0x31,0x31,0x30,0x30,0x30}, {0x47,0x30,0x30,0x30,0x30,0x30,0x31,0x31,0x30,0x31},{0x48,0x31,0x30,0x30,0x30,0x30,0x31,0x31,0x30,0x30},{0x49,0x30,0x30,0x31,0x30,0x30,0x31,0x31,0x30,0x30},{0x4a,0x30,0x30,0x30,0x30,0x31,0x31,0x31,0x30,0x30},{0x4b,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x31},{0x4c,0x30,0x30,0x31,0x30,0x30,0x30,0x30,0x31,0x31},{0x4d,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x31,0x30},{0x4e,0x30,0x30,0x30,0x30,0x31,0x30,0x30,0x31,0x31},{0x4f,0x31,0x30,0x30,0x30,0x31,0x30,0x30,0x31,0x30},{80,0x30,0x30,0x31,0x30,0x31,0x30,0x30,0x31,0x30},{0x51,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x31,0x31},{0x52,0x31,0x30,0x30,0x30,0x30,0x30,0x31,0x31,0x30},{0x53,0x30,0x30,0x31,0x30,0x30,0x30,0x31,0x31,0x30},{0x54,0x30,0x30,0x30,0x30,0x31,0x30,0x31,0x31,0x30},{0x55,0x31,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x31},{0x56,0x30,0x31,0x31,0x30,0x30,0x30,0x30,0x30,0x31}, {0x57,0x31,0x31,0x31,0x30,0x30,0x30,0x30,0x30,0x30},{0x58,0x30,0x31,0x30,0x30,0x31,0x30,0x30,0x30,0x31},{0x59,0x31,0x31,0x30,0x30,0x31,0x30,0x30,0x30,0x30},{90,0x30,0x31,0x31,0x30,0x31,0x30,0x30,0x30,0x30},{0x2d,0x30,0x31,0x30,0x30,0x30,0x30,0x31,0x30,0x31},{0x2e,0x31,0x31,0x30,0x30,0x30,0x30,0x31,0x30,0x30},{0x20,0x30,0x31,0x31,0x30,0x30,0x30,0x31,0x30,0x30},{0x2a,0x30,0x31,0x30,0x30,0x31,0x30,0x31,0x30,0x30},{0x24,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30},{0x2f,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x31,0x30},{0x2b,0x30,0x31,0x30,0x30,0x30,0x31,0x30,0x31,0x30},{0x25,0x30,0x30,0x30,0x31,0x30,0x31,0x30,0x31,0x30} }; //code39合法字符集[0-9A-Z+-*/%.]共43个 privatebyte[]c39_cw=newbyte[]{ 0x30,0x31,50,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,70, 0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,80,0x51,0x52,0x53,0x54,0x55,0x56, 0x57,0x58,0x59,90,0x2d,0x2e,0x20,0x24,0x2f,0x2b,0x25 }; privatebyte[,]c39_ex=newbyte[,]{ {1,0x24,0x41},{2,0x24,0x42},{3,0x24,0x43},{4,0x24,0x44},{5,0x24,0x45},{6,0x24,70},{7,0x24,0x47},{8,0x24,0x48},{9,0x24,0x49},{10,0x24,0x4a},{11,0x24,0x4b},{12,0x24,0x4c},{13,0x24,0x4d},{14,0x24,0x4e},{15,0x24,0x4f},{0x10,0x24,80}, {0x11,0x24,0x51},{0x12,0x24,0x52},{0x13,0x24,0x53},{20,0x24,0x54},{0x15,0x24,0x55},{0x16,0x24,0x56},{0x17,0x24,0x57},{0x18,0x24,0x58},{0x19,0x24,0x59},{0x1a,0x24,90},{0x1b,0x25,0x41},{0x1c,0x25,0x42},{0x1d,0x25,0x43},{30,0x25,0x44},{0x1f,0x25,0x45},{0x3b,0x25,70}, {60,0x25,0x47},{0x3d,0x25,0x48},{0x3e,0x25,0x49},{0x3f,0x25,0x4a},{0x5b,0x25,0x4b},{0x5c,0x25,0x4c},{0x5d,0x25,0x4d},{0x5e,0x25,0x4e},{0x5f,0x25,0x4f},{0x7b,0x25,80},{0x7c,0x25,0x51},{0x7d,0x25,0x52},{0x7e,0x25,0x53},{0x7f,0x25,0x54},{0,0x25,0x55},{0x40,0x25,0x56}, {0x60,0x25,0x57},{0x21,0x2f,0x41},{0x22,0x2f,0x42},{0x23,0x2f,0x43},{0x26,0x2f,70},{0x27,0x2f,0x47},{40,0x2f,0x48},{0x29,0x2f,0x49},{0x2a,0x2f,0x4a},{0x2c,0x2f,0x4c},{0x3a,0x2f,90},{0x61,0x2b,0x41},{0x62,0x2b,0x42},{0x63,0x2b,0x43},{100,0x2b,0x44},{0x65,0x2b,0x45}, {0x66,0x2b,70},{0x67,0x2b,0x47},{0x68,0x2b,0x48},{0x69,0x2b,0x49},{0x6a,0x2b,0x4a},{0x6b,0x2b,0x4b},{0x6c,0x2b,0x4c},{0x6d,0x2b,0x4d},{110,0x2b,0x4e},{0x6f,0x2b,0x4f},{0x70,0x2b,80},{0x71,0x2b,0x51},{0x72,0x2b,0x52},{0x73,0x2b,0x53},{0x74,0x2b,0x54},{0x75,0x2b,0x55}, {0x76,0x2b,0x56},{0x77,0x2b,0x57},{120,0x2b,0x58},{0x79,0x2b,0x59},{0x7a,0x2b,90} }; #endregion #region字段和属性 privatebool_checksum; privatestring_dataToEncode; privatebool_humanReadable; privatestring_humanReadableFont; privatefloat_humanReadableSize; privatefloat_marginX; privatefloat_marginY; privatefloat_moduleHeight; privatefloat_moduleWidth; privatefloat_ratio; privatefloat_reduction; privateColor_codeBarColor=Color.Black; privatebool_isDisplayCheckCode; privatestring_checkData; privatebool_isDisplayStartStopSign; ///<summary> ///是否检查效验 ///</summary> publicboolChecksum { get { return_checksum; } set { _checksum=value; } } ///<summary> ///要进行编码的数据 ///</summary> publicstringDataToEncode { get { return_dataToEncode; } set { _dataToEncode=value; } } ///<summary> ///是否显示文本内容 ///</summary> publicboolHumanReadable { get { return_humanReadable; } set { _humanReadable=value; } } ///<summary> ///用于显示文本内容的字体 ///</summary> publicstringHumanReadableFont { get { return_humanReadableFont; } set { _humanReadableFont=value; } } ///<summary> ///用于显示文本内容文字的代大小 ///</summary> publicfloatHumanReadableSize { get { return_humanReadableSize; } set { _humanReadableSize=value; } } ///<summary> ///水平方向边距 ///水平方向建议尽量留白 ///如果没有留白同时模块宽度较小可能会造成无法识别 ///</summary> publicfloatMarginX { get { return_marginX; } set { _marginX=value; } } ///<summary> ///垂直方向边距 ///</summary> publicfloatMarginY { get { return_marginY; } set { _marginY=value; } } ///<summary> ///模块高度(mm) ///</summary> publicfloatModuleHeight { get { return_moduleHeight; } set { _moduleHeight=value; } } ///<summary> ///模块宽度(mm) ///模块宽度不应低于0.2646f ///模块宽度过低会造成数据丢失因而读不出数据或者会误读 ///</summary> publicfloatModuleWidth { get { return_moduleWidth; } set { _moduleWidth=value; } } ///<summary> ///放大比率 ///</summary> publicfloatRatio { get { return_ratio; } set { _ratio=value; } } ///<summary> ///缩小 ///</summary> publicfloatReduction { get { return_reduction; } set { _reduction=value; } } ///<summary> ///设置条形码的颜色 ///</summary> publicColorCodeBarColor { get { return_codeBarColor; } set { _codeBarColor=value; } } ///<summary> ///是否显示效验码 ///此属性要在Checksum属性为true的情况下有用 ///</summary> publicboolIsDisplayCheckCode { get{returnthis._isDisplayCheckCode;} set{this._isDisplayCheckCode=value;} } ///<summary> ///供人识别是否显示起止符 ///</summary> publicboolIsDisplayStartStopSign { get{returnthis._isDisplayStartStopSign;} set{this._isDisplayStartStopSign=value;} } #endregion ///<summary> ///默认构造函数 ///初始化 ///</summary> publicCSharpCode39() { this.initData(); } publicCSharpCode39(stringdataToEncode) { this.initData(); this._dataToEncode=dataToEncode; } ///<summary> ///默认构造函数 ///初始化数据 ///</summary> privatevoidinitData() { this._humanReadableFont="Arial"; this._humanReadableSize=10f; this._codeBarColor=Color.Black; this._moduleHeight=15f;//模块高度毫米 this._moduleWidth=0.35f;//模块宽度毫米 this._ratio=3f; this._marginX=2; this._marginY=2; this._checksum=true; this._isDisplayCheckCode=false; this._isDisplayStartStopSign=false; } privatechar[]_bitpattern_c39(stringrawdata,refintfinalLength) { //0x2739 //0x5080 if((rawdata.Length==0)||(rawdata.Length>0x50/*0x27*/)) { returnnull; } for(inti=0;i<rawdata.Length;i++) { if((rawdata[i]=='\0')||(rawdata[i]>'\x007f')) { returnnull; } } byte[]data=processTilde(rawdata); if(data.Length==0) { returnnull; } byte[]buffer2=this.processExtended(data); if((buffer2.Length==0)||(buffer2.Length>/*40*/80)) { returnnull; } finalLength=this._checksum?((buffer2.Length+2)+1):(buffer2.Length+2); returnthis.getPattern_c39(buffer2); } ///<summary> ///计算效验值 ///</summary> ///<paramname="data"></param> ///<paramname="len"></param> ///<returns></returns> privatebyte_checksum_c39(byte[]data,intlen) { //0x2b43 //字符值的总和除以合法字符集的个数43取余数余数在合法字符数组中对应的数值就是效验值 intnum2=0; for(inti=1;i<len;i++) { num2+=this.valueFromCharacter(data[i]); } returnthis.c39_cw[num2%0x2b]; } privatechar[]Code39_bitpattern(stringdataToEncode) { intfinalLength=0; returnthis._bitpattern_c39(dataToEncode,reffinalLength); } ///<summary> ///获得Code39条码图片 ///</summary> ///<paramname="resolution">DPI</param> ///<returns></returns> publicBitmapgetBitmapImage(floatresolution) { returnCode39_createCode(resolution); } privateBitmapCode39_createCode(floatresolution) { intnum6; intfinalLength=0; char[]chArray=this._bitpattern_c39(DataToEncode,reffinalLength); if(chArray==null) { returnnull; } floatfontsize=this._humanReadable?(0.3527778f*this._humanReadableSize):0f; //floatnum3=(7f*ModuleWidth)+((3f*Ratio)*ModuleWidth); floatnum3=(7f*this._moduleWidth)+((3f*this._ratio)*this._moduleWidth); floatwidth=(finalLength*num3)+(2f*this._marginX); floatheight=(this._moduleHeight+(2f*this._marginY))+fontsize; width*=resolution/25.4f; height*=resolution/25.4f; Bitmapimage=newBitmap((int)width,(int)height,PixelFormat.Format32bppPArgb); image.SetResolution(resolution,resolution); //image.SetResolution(300,300); Graphicsg=Graphics.FromImage(image); g.Clear(Color.White); g.PageUnit=GraphicsUnit.Millimeter;//以毫米为度量单位 g.FillRectangle(newSolidBrush(Color.White),newRectangle(0,0,/*(int)width*/image.Width,/*(int)height*/image.Height)); //newPen(Color.Black,2f); //newSolidBrush(Color.White); SolidBrushbrush=newSolidBrush(Color.Black); if(resolution<300f) { //g.TextRenderingHint=TextRenderingHint.AntiAlias; //g.SmoothingMode=SmoothingMode.AntiAlias; g.CompositingQuality=CompositingQuality.HighQuality; //g.SmoothingMode=SmoothingMode.HighQuality; g.InterpolationMode=InterpolationMode.HighQualityBicubic; g.TextRenderingHint=TextRenderingHint.AntiAliasGridFit; } floatnum7=0f; for(num6=0;num6<chArray.Length;num6++) { if(chArray[num6]=='0') { if((num6&1)!=1) { RectangleFrect=newRectangleF(MarginX+num7,MarginY,ModuleWidth,ModuleHeight); MakeBar(g,rect,Reduction); } num7+=1f*ModuleWidth; } else { if((num6&1)!=1) { RectangleFef2=newRectangleF(MarginX+num7,MarginY,Ratio*ModuleWidth,ModuleHeight); MakeBar(g,ef2,Reduction); } num7+=Ratio*ModuleWidth; } } #region供人识别内容 if(this._humanReadable) { #region保留 /*byte[]buffer2=processTilde(this._dataToEncode); intindex=0; List<byte>arr=newList<byte>(); for(num6=0;num6<buffer2.Length;num6++) { //0x20320x7e126 if((buffer2[num6]>=0x20)&&(buffer2[num6]<=0x7e)) { arr.Add(buffer2[num6]); } } byte[]bytes=newbyte[arr.Count]; for(inti=0;i<arr.Count;i++) { bytes[i]=arr[i]; } index=arr.Count; //stringtext=newASCIIEncoding().GetString(bytes,0,index); */ #endregion stringtext=this._dataToEncode; if(this._isDisplayCheckCode&&!string.IsNullOrEmpty(this._checkData)){ text+=this._checkData; } if(this._isDisplayStartStopSign) { text="*"+text+"*"; } Fontfont=newFont(this._humanReadableFont,this._humanReadableSize); //g.DrawString(text,font,brush,newPointF(MarginX,MarginY+ModuleHeight)); //新增字符串格式 vardrawFormat=newStringFormat{Alignment=StringAlignment.Center}; floatinpix=image.Width/resolution;//根据DPi求出英寸数 floatwidthmm=inpix*25.4f;//有每英寸像素求出毫米 //g.DrawString(text,font,Brushes.Black,width/2,height-14,drawFormat); g.DrawString(text,font,/*Brushes.Black*/brush,newPointF(/*MarginX*/(int)(widthmm/2),MarginY+ModuleHeight+1),drawFormat); } #endregion returnimage; } ///<summary> ///进行图形填充 ///</summary> ///<paramname="g"></param> ///<paramname="rect"></param> ///<paramname="reduction"></param> privatevoidMakeBar(Graphicsg,RectangleFrect,floatreduction) { MakeBar(g,rect,reduction,this._codeBarColor); } ///<summary> ///进行图形填充 ///</summary> ///<paramname="g"></param> ///<paramname="rect"></param> ///<paramname="reduction"></param> ///<paramname="brushColor"></param> privatevoidMakeBar(Graphicsg,RectangleFrect,floatreduction,ColorbrushColor) { floatnum=rect.Width*(reduction/200f); floatnum2=rect.Width-(rect.Width*(reduction/200f)); RectangleFef=newRectangleF { X=rect.X+num, Y=rect.Y, Width=num2, Height=rect.Height }; SolidBrushbrush=newSolidBrush(brushColor); g.FillRectangle(brush,ef); } privatechar[]getPattern_c39(byte[]data) {//0x2a42为* //intnum=0x27; intnum=80; byte[]buffer=newbyte[num+1]; buffer[0]=0x2a; intindex=1; for(inti=0;i<data.Length;i++) { buffer[index]=data[i]; index++; } if(Checksum) { buffer[index]=this._checksum_c39(buffer,index); if(_isDisplayCheckCode) { this._checkData=((char)buffer[index]).ToString(); } index++; } buffer[index]=0x2a; index++; char[]chArray=newchar[index*10]; intnum5=0; for(intj=0;j<index;j++) { bytec=buffer[j]; intnum9=this.indexFromCharacter(c); for(intk=0;k<9;k++) { chArray[num5]=(char)this.c39_bp[num9,k+1]; num5++; } chArray[num5]='0'; num5++; } returnchArray; } privateintindexFromCharacter(bytec) { //0x2c==44 for(inti=0;i<0x2c;i++) { if(this.c39_bp[i,0]==c) { returni; } } return-1; } privatebyte[]processExtended(byte[]data) { //0x2538 //0x4F790x4E78 //intnum=0x4F; intnum=data.Length-1; byte[]sourceArray=newbyte[num+1]; intindex=0; for(inti=0;i<data.Length;i++) { bytec=data[i]; if(this.valueFromCharacter(c)!=-1) { sourceArray[index]=c; index++; } else { bytenum5=0; bytenum6=0; if(this.valuesFromExtended(c,refnum5,refnum6)) { sourceArray[index]=num5; sourceArray[index+1]=num6; index+=2; } } } byte[]destinationArray=newbyte[index]; Array.Copy(sourceArray,destinationArray,index); returndestinationArray; } ///<summary> ///返回指定字符在code39合法字符数组中对应的索引 ///</summary> ///<paramname="c"></param> ///<returns></returns> privateintvalueFromCharacter(bytec) { //c39_cw为数组,保存的为合法的字符集信息[0-9A-Z+-*/%.]共43个 //如果存在这个字符就返回c39_cw对应的索引 for(inti=0;i</*0x2b*/this.c39_cw.Length;i++) { if(this.c39_cw[i]==c) { returni; } } return-1; } ///<summary> ///判断字符集是否存在Extended ///</summary> ///<paramname="c"></param> ///<paramname="v1"></param> ///<paramname="v2"></param> ///<returns></returns> privateboolvaluesFromExtended(bytec,refbytev1,refbytev2) { //0x5585 for(inti=0;i<0x55;i++) { if(this.c39_ex[i,0]==c) { v1=this.c39_ex[i,1]; v2=this.c39_ex[i,2]; returntrue; } } returnfalse; } privatebyte[]processTilde(stringrawdata) { byte[]sourceArray=newbyte[rawdata.Length]; intindex=0; for(inti=0;i<rawdata.Length;i++) { if(rawdata[i]!='~') { sourceArray[index]=(byte)rawdata[i]; index++; } elseif((i+3)<rawdata.Length) { stringstr=newstring(newchar[]{rawdata[i+1],rawdata[i+2],rawdata[i+3]}); intnum3=Convert.ToInt32(str,10); if((num3>0)&&(num3<=0xff)) { sourceArray[index]=(byte)num3; index++; } if(num3==0x3e7) { sourceArray[index]=0x86; index++; } i+=3; } else { sourceArray[index]=(byte)rawdata[i]; index++; } } byte[]destinationArray=newbyte[index]; Array.Copy(sourceArray,destinationArray,index); returndestinationArray; } }
这个方法是根据DPI以及数据模块的高宽来确定条码的实际高宽。模块的宽度以毫米(mm)来算。类中的getBitmapImage方法的一个参数getBitmapImage为DPI。安卓用户安装平时常用的扫码软件即可做识别测试。就识别率来说还是可以的,扫描枪绝对是可以扫的出的。同时使用过MessagingToolkit.Barcode进行解码测试,万张无一误读。
以上内容就是本文的全部内容,希望大家喜欢。