吵吵   2013-09-13  阅读:4,144

条形码或称条码(barcode)是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息的图形标识符。条形码技术主要原理是利用了光的反射,白色物体能反射各种波长的可见光,黑色物体则吸收各种波长的可见光,所以当条形码扫描器光源发出的光在条形码上反射后,反射光照射到条码扫描器内部的光电转换器上,光电转换器根据强弱不同的反射光信号,转换成相应的电信号。

第一个条形码是与食品有关的,1949年美国人诺曼·伍德兰和伯尼·西尔法(Berny Silver)申请了用于食品自动识别领域的环形条形码。

常用的一维条形码标准包括三九码、二五码、EAN 128码等等,本文只讨论一维码的生成和打印编程,二维码等不再说明。

常用的条码生成和打印编程方式包括以下三种:

一、条码字体。

使用条码字体来生成和打印条码是最简单的,因为只要直接调用字体就好了,但是使用字体生成的条码打印后分辨率十分低。此种技术一般使用39码来编码,因为39码的条形比较宽,相对于其他编码格式的条形码,识别率比较高。但是过宽的因素又会导致打印出来的条码很大,以吵吵的实验为例,用39码字体打印出来12位数的条码,长度达到5厘米左右,手持的扫描枪才比较容易识别。

所以该种方式只适合足够大的页面打印,而且识别率不是很高。

二、Excel控件调用方式。

Excel中有一个控件叫做Microsoft BarCode 控件9.0,该控件属于ActiveX控件,这意味着你可以在其它应用程序中调用该控件来生成条码。

使用该控件可以方便的生成条码,但是这个控件并不是那么好用。它是一个有界面的控件,大小比较难以调整,吵吵用的时候,还出现了一个问题是,当条码生成之后,我去读它的图片,由于控件还没刷新,结果读到张空白图片。

三、BCEncode.dll。

如果要打印识别率十分高的条码,条码一定是一个像素一个像素点画的,但是由于规则的复杂等原因,我们就不再去自己慢慢画了,那么有什么好一点库和类封装好了么?

BCEncode.dll是一个是我找到的一个比较好用的动态库,该库可以通过API的调用方式生成我们需要的条码,然后返回Windows的位图句柄HBitmap,有了这张位图,我们就可以任意去绘制条码了。

通过吵吵的实验,使用25码编码,12位的数字编码后的条码宽度只有1.5厘米的时候,识别率还特别的高,基本扫描无障碍。用于吵吵试剂管理系统的条码就是用这个生成的25码,12位数字,条码大概2.5厘米左右,识别率100%。

条码

以下是用dlephi写的一个条码打印类,用于打印试剂的条码、名称、过期日期和批号:

unit FMBarCode;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls,Vcl.Printers,System.StrUtils;
type
  BarPrintInfo=record
    Bar:string[20];
    RegentName:string[50];
    Lot:string[20];
    ExpireDate:string[30];
  end;

type
  TFMBarCode = class(TObject)
    constructor Create(APrinterIndex:Integer);
    destructor Destroy();
    function MakeBarCode(ABar:string):HBITMAP;
    function AddBar(ABarPrint:BarPrintInfo):Boolean;
    procedure Print();
  private
    { Private declarations }
    FHDLL:THandle;
    FaryBar:array of BarPrintInfo;
    FPrinterIndex:Integer;
  public
    { Public declarations }
  end;
 TMakeBarcodeBmpFile=Function  (lpszFileName:AnsiString;lDpi:DWORD;nBType:Integer;lpszText:AnsiString; nNarrow:integer;nWide:integer;nHeight:Integer;nRotate:Integer;nReadable:Integer; err:DWORD):DWORD;stdcall;
 TMakeBarCode=function (nBtype:Integer;lpszText:AnsiString;nNarrow:Integer;nWide:integer;nHeight:Integer;nRotate:Integer;nReadable:Integer; err:DWORD):HBITMAP;stdcall;


implementation

constructor TFMBarCode.Create(APrinterIndex:Integer);
begin
  FPrinterIndex:=APrinterIndex;
  Printer.PrinterIndex:=FPrinterIndex;
  FHDLL:= LoadLibrary('BCEncode.dll');
  SetLength(FaryBar,0);

end;

destructor TFMBarCode.Destroy();
begin
  FreeLibrary(FHDLL);
end;
function TFMBarCode.MakeBarCode(ABar:string):HBITMAP;
var
  funcMakeBarCode:TMakeBarCode;
begin
  funcMakeBarCode:=GetProcAddress(FHDLL, 'MakeBarCode');
  result:=funcMakeBarCode(5,ABar,2,4,60,0,3,0);
end;

function TFMBarCode.AddBar(ABarPrint:BarPrintInfo):Boolean;
var
  iCount:Integer;
begin
  iCount:=length(FaryBar);
  SetLength(FaryBar,icount+1);
  FaryBar[iCount].Bar:=ABarPrint.Bar;
  FaryBar[iCount].RegentName:=ABarPrint.RegentName;
  FaryBar[iCount].Lot:=ABarPrint.Lot;
  FaryBar[iCount].ExpireDate:=ABarPrint.ExpireDate;

  Result:=True;
end;

procedure TFMBarCode.Print();
var
iTotal:Integer;
iRow:Integer;
iCol:Integer;
iCurrent:Integer;
j,k:Integer;
  i: Integer;
bmpBar:TBitmap;
begin
  bmpBar:=TBitmap.Create;
  iTotal:=Length(FaryBar);
  iRow:=(iTotal div 3)+1;
  if (iTotal mod 3)=0 then iRow:=iRow-1;


  iCol:=3;
  iCurrent:=0;
  Printer.BeginDoc;
  for j := 0 to irow-1 do
  begin
    for k := 0 to icol-1 do
    begin
      if iCurrent=iTotal then Break;
      bmpBar.Handle:=MakeBarCode(FaryBar[iCurrent].Bar);
      Printer.Canvas.Draw(10+k*290,0,bmpBar);
      Printer.Canvas.TextOut(10+k*290,70,leftstr(FaryBar[iCurrent].RegentName,20));
      //Printer.Canvas.TextOut(10+k*290,100,leftstr(12,24,FaryBar[iCurrent].RegentName));
      Printer.Canvas.TextOut(10+k*290,150,'Lot:'+FaryBar[iCurrent].Lot);
      Printer.Canvas.TextOut(10+k*290,180,'Exp:'+FaryBar[iCurrent].ExpireDate);
      iCurrent:=iCurrent+1;


    end;
    if j<>(iRow-1) then Printer.NewPage;
  end;
  Printer.EndDoc;

end;
end.

吵吵微信朋友圈,请付款实名加入:

吵吵 吵吵

8条回应:“条码生成与打印”

  1. aecth说道:

    dlephi 写错了,delphi

  2. zhouleyu说道:

    呵呵 支持吧

  3. 路过,赞一个

  4. 广告联盟说道:

    说得对 支持

  5. keyii说道:

    吵吵有BCEncode的说明文档吗,或者能打印的源代码,不知道函数干嘛的

    • 吵吵说道:

      函数是返回一个bitmap,即一个位图,你把图片打印出来就好了。

  6. 嫦曦说道:

    经验啊… 向博主学习

发表评论

电子邮件地址不会被公开。 必填项已用*标注