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进行解码测试,万张无一误读。
以上内容就是本文的全部内容,希望大家喜欢。