Delphi集成二维码实战:基于ZXing.Delphi的生成与识别

发布时间:2026/9/3 17:56:17
Delphi集成二维码实战:基于ZXing.Delphi的生成与识别 简介ZXing.Delphi-3.9.0.zip是一份面向Delphi开发者的条形码/二维码解决方案适用于从Delphi XE到10.3.3 Rio的多个版本可快速为桌面或移动应用加入扫码与识读能力。资源包共263个文件大小15.5MB核心包括92个.pas单元源码、8个.dpr/.dproj工程文件及6个.fmx跨平台界面文件另有107个.png图片、示例位图、res资源、deployproj部署配置等便于直接参照demo工程进行二次开发。已有496人学习下载。通过该库可识别Code 39、QR Code、Data Matrix、EAN-13等主流格式并支持扫码结果的实时事件回调同时提供扫描区域、解码参数等配置项方便针对不同业务场景做优化。压缩包内还包含源码级组件、示例工程与相关文档可帮助开发者快速理解封装逻辑将其集成进物流、支付、票据管理等实际项目中。 搞Delphi开发的兄弟十有八九会遇到这样的需求给桌面程序加个二维码生成或者让它能扫个码。我自己第一次接触ZXing.Delphi-3.9.0.zip这个包是给一套设备管理系统做配件追溯模块当时被二维码需求卡了整整一个下午——网上关于Delphi调用ZXing的资料鱼龙混杂很多还停留在旧版API。后来把3.9.0这个zip彻底吃透之后发现确实好用而且比我预想的要简单。这篇就把完整过程写下来从解压配置、跑通Demo、生成与识别二维码到批量处理Excel数据、常见坑的排查一次讲明白。适合准备在Delphi项目里集成二维码功能的开发者也适合想快速评估ZXing.Delphi能不能用的朋友。1. ZXing.Delphi是什么从Zebra Crossing说起1.1 一个Java库的Delphi重生ZXingZebra Crossing最早是Google发起的开源二维码/条码处理库用Java写成一度是安卓生态处理条码的事实标准。后来社区陆陆续续把它移植到很多语言ZXing.Delphi就是其中比较活跃的一个分支——它把ZXing核心的编码、解码、图像分析逻辑用Object Pascal重新实现了一遍从源码层面就是纯粹的Delphi代码不是封装DLL也不是靠桥接调用Java。这意味着什么你不需要安装额外的运行时不需要担心目标机器有没有JRE编译出来就是一个标准的Delphi项目可以很自然地跟VCL、FireMonkey、各种第三方组件混用。我有个老项目跑在旧工控机上ZXing.Delphi照样能编进去跑起来这就是纯移植方案最实在的优势。1.2 为什么我用它而不是其他方案当时摆在我面前的无非几条路调Web API生成二维码、买商业控件、自己写位图算法、用OpenCV做识别以及ZXing.Delphi。我逐一排过雷调Web API生成二维码最省事但二维码内容一旦是客户内部信息走外部接口就有泄露风险而且离线环境直接没法用。商业控件功能完善但授权费不便宜而且有些老牌控件在64位支持上并不友好。自己写生成算法二维码生成表面上不复杂但涉及Reed-Solomon纠错编码、掩码、版本选择没个把月调不完识别就更别想了。OpenCV重量级配置繁琐对扫码这个场景属于杀鸡用牛刀。最后对比下来ZXing.Delphi免费、离线可用、源码看得见、社区活跃度高正好卡在所有痛点的解集上。而且从3.x版本开始它对二维码的生成和识别都封装得非常顺手不需要自己写底层的位运算和图像处理逻辑。2. 环境准备解压、路径配置与第一个Demo2.1 解压后先认准这几个目录ZXing.Delphi-3.9.0.zip解压后里面大致是这几个部分Docs文档和版本说明建议先翻一下能避免很多低级问题。Lib预编译好的DCU文件按平台和编译选项分了子目录。Source核心源码这是最值钱的部分所有ZXing.*单元都在这里。Demo自带示例生成和识别都有。Resources示例用的测试图片用来验证识别功能最方便。我第一次拿到包时没仔细看Lib目录直接拿Source里的单元去编译结果各种找不到DCU。后来才发现ZXing.Delphi的源码是按ZXing.前缀组织的把Source目录加进Library PathDelphi会自动编译需要的单元根本不用一个个手动添加。2.2 Library Path的配置细节打开Delphi进入Tools Options Delphi Options Library在Library path里把Source目录加进去。这个操作跟普通第三方库是一样的但有三个细节值得注意路径里不要带中文、不要带空格某些版本的Delphi对这类路径解析经常出幺蛾子。32位和64位平台都要分别确认一下如果你项目切到Win64Library Path没配好编译报错会非常难查。配置完建议重启一次IDE我就遇到过缓存导致的明明加了路径还是找不到单元。配好之后随便新建一个VCL工程在uses里写上ZXing.BarcodeFormat如果能编译过去说明路径配置成功。2.3 跑通Demo比什么都重要我建议你先别急着往自己项目里塞代码先把Demo跑起来。ZXing.Delphi-3.9.0自带示例里一般有两个演示一个生成二维码一个从图片或摄像头识别条码。把Demo编译运行生成一张二维码再识别回来确认整个链路是通的再开始写自己的业务逻辑。这一步能节省大量排查时间——毕竟Demo都跑不起来的话问题大概率是环境不是你的代码。3. 核心实操生成二维码的完整代码3.1 生成二维码由字符串到位矩阵再到TBitmapZXing.Delphi生成二维码的核心思路很有意思它不是直接输出图片而是输出一个BitMatrix位矩阵。你可以把它理解成一个二维bool数组True代表黑色模块False代表白色模块。拿到这个矩阵之后怎么变成图片、变成什么格式完全由你自己决定。这个设计让库的复用性很高——你要生成到TBitmap、TImage还是直接打印到Canvas上都行。下面这段代码是我在Delphi 10.4下验证过的uses System.SysUtils, Vcl.Graphics, ZXing.BarcodeFormat, ZXing.QrCode.Internal.QRCodeWriter, ZXing.Common.BitMatrix; procedure TForm1.Button1Click(Sender: TObject); var LWriter: TQRCodeWriter; LMatrix: TBitMatrix; LBitmap: TBitmap; X, Y: Integer; begin LWriter : TQRCodeWriter.Create; try LMatrix : LWriter.encode(edtContent.Text, TBarcodeFormat.QR_CODE, 300, 300); finally LWriter.Free; end; if LMatrix nil then begin ShowMessage(生成失败请检查内容长度); Exit; end; LBitmap : TBitmap.Create(300, 300); try for Y : 0 to LMatrix.Height - 1 do for X : 0 to LMatrix.Width - 1 do begin if LMatrix[X, Y] then LBitmap.Canvas.Pixels[X, Y] : clBlack else LBitmap.Canvas.Pixels[X, Y] : clWhite; end; Image1.Picture.Assign(LBitmap); finally LBitmap.Free; LMatrix.Free; end; end;几点说明encode方法有多个重载上面的写法指定了内容、格式、宽高实际还能传TEncodeHint对象下面会讲。如果你的3.9.0包里单元结构略有差异请以Demo实际引用的单元名为准核心调用逻辑是一样的。用Canvas.Pixels逐点画在200x200以内还凑合到了300x300以上速度肉眼可见地下降。生产环境建议改用ScanLine按行填充或者先把位图画到小尺寸再拉伸。生成失败时不一定会抛异常有可能返回nil所以判空不要省。3.2 识别二维码TScanManager的一行扫描如果说生成是从字符串到图片识别就是完全相反的方向。ZXing.Delphi的识别入口封装得很简单核心就一个TScanManageruses ZXing.ScanManager, ZXing.BarcodeFormat, ZXing.ReadResult; function ScanQrCodeFromBitmap(ABitmap: TBitmap): string; var LScanner: TScanManager; LResult: TReadResult; begin Result : ; LScanner : TScanManager.Create(TBarcodeFormat.QR_CODE, nil); try LResult : LScanner.Scan(ABitmap); if LResult nil then try Result : LResult.Text; finally LResult.Free; end; finally LScanner.Free; end; end;这个函数接收一个TBitmap返回二维码文本。如果扫不出来返回空字符串。TScanManager构造函数的第一个参数是条码格式可以传具体的TBarcodeFormat.QR_CODE也可以传TBarcodeFormat.Auto让它自动识别。但自动识别速度稍慢而且误判率会高一些。批量识别时明确指定格式通常更可靠。3.3 让二维码更好用纠错级别与空白边距初次玩ZXing的人容易忽略两个参数纠错级别和空白边距。这两样直接决定二维码在实际场景中能不能被稳定扫出来。纠错级别分为L约7%、M约15%、Q约25%、H约30%四档。数据量固定的情况下纠错级别越高二维码越密集、越难扫。日常场景我一般用M如果二维码会印在不平整的表面比如纸箱、塑封袋升到Q更稳妥。空白边距二维码四周至少要留出4个模块宽度的空白否则扫码枪很容易识别失败。ZXing在默认情况下会带一点Margin通过TEncodeHint可以手动控制。用TEncodeHint生成带参数的二维码代码大概是这个套路uses ZXing.Common.EncodingHint; var LHint: TEncodeHint; begin LHint : TEncodeHint.Create; try LHint.Margin : 4; // 空白边距 LHint.ErrorCorrection : TErrorCorrectionLevel.M; LHint.Encoding : TEncoding.UTF8; // 中文内容编码 LMatrix : LWriter.encode(edtContent.Text, TBarcodeFormat.QR_CODE, 300, 300, LHint); finally LHint.Free; end; end;Encoding这个参数尤其关键处理中文内容时如果不指定UTF-8很多扫码设备扫出来就是乱码。这个坑我后面还会再说一次因为踩的人实在太多了。4. 常见问题与排查技巧实录4.1 zxing库是c的吗以及编译期报错的真相我经常在搜索引擎里看到有人问zxing库是c的吗这里明确说一下ZXing原生是Java实现的社区里有各种语言的移植版其中C版叫zxing-cpp而ZXing.Delphi是Object Pascal的完整移植两者互不兼容。如果你在Delphi项目里引入的是ZXing.Delphi那么编译期报错基本跟这是不是C写的没关系更多是下面这几种情况找不到ZXing.*单元Library Path没配好或者Delphi缓存路径失效重启IDE或重新配置就好。提示某个类方法不存在你下载的可能是旧版本源码而文章或教程用的是新版API。ZXing.Delphi在2.x和3.x之间API差异非常大务必以3.9.0包内Demo为准。编译报DCU版本太新Lib目录下的预编译DCU是给特定Delphi版本用的跨版本使用建议直接删掉Lib用Source重新编译。排查这类问题有个通用思路先新建一个干净的VCL工程只引用一个ZXing单元编译通过后逐步加入功能代码这样能把环境问题和代码问题快速隔离开。4.2 中文乱码编码导致的经典事故用ZXing.Delphi生成带中文的二维码如果直接写writer.encode(你好, ...)大概率会踩到编码坑。原因在于ZXing内部处理字符串时如果不指定编码Delphi的Unicode字符串和ZXing内部使用的字节序列对不上结果就是扫码枪拿到一堆乱码中文直接变成问号。解决办法有两个层次生成侧通过TEncodeHint.Encoding : TEncoding.UTF8明确指定编码这一步最关键。识别侧调用TScanManager.Scan拿到LResult.Text后通常是正常字符串但如果你自己对图片做了字节层面的预处理统一用UTF-8解码即可。另外多说一句如果二维码内容是URL、英文加数字编码问题不会暴露一旦换成商品名、客户名称、人员姓名这类中文千万记得验证一遍中文链路。我见过不止一个项目上线后才发现扫码结果是乱码。4.3 识别率低先检查这四件事如果你的程序扫一张清晰度正常的二维码还是经常失败建议按这个顺序排查对比度图片是否足够黑白分明灰底、浅色背景、照明不均都会让识别算法抓不住模块边缘。分辨率二维码区域在图片中如果只占很小一块ZXing很难识别。通常二维码区域的像素宽度不要低于200像素否则请在代码里先做裁剪或放大。干扰图案二维码正中间放Logo、周围有花纹、靠近文字都会干扰定位角三个大黑方块的检测。旋转角度ZXing对旋转有一定容忍度但超过15度的倾斜会显著降低识别成功率工业摄像头场景建议先做透视校正。实测下来把位图先转成灰度图再扫描识别成功率会明显提升。ZXing.Delphi内部其实也做灰度化但如果你在传入前自己用图形库预处理一下效果会更好。4.4 版本兼容性10.4到新版Delphi我主力开发环境是Delphi 10.4ZXing.Delphi-3.9.0在这个版本下编译、运行、调试没遇到任何问题。如果你的环境更新比如12.x甚至是新一代命名大概率也能直接编过因为3.9.0本文还有配套的精品资源点击获取