65.9K
CodeProject 正在变化。 阅读更多。
Home

读取图像中的条形码 - III

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (118投票s)

2009年10月5日

CPOL

4分钟阅读

viewsIcon

1204830

downloadIcon

95628

检测Code39、EAN和Code128条形码图像。

Screenshot

致谢

本项目基于CodeProject文章:图像条形码读取 - II,作者是qlipoth。我已征得qlipoth许可,发布了他代码的增强版本。

引言

我的公司需要读取包含文本的图像中的条形码。在搜索C#解决方案时,我找到了qlipoth的CodeProject文章:图像条形码读取 - II。他的代码在很大程度上满足了我的需求,但我需要一些改进。最终,我的修改 amounted to a significant rewrite that justifies a new CodeProject publication. (我的修改最终 amounted to a significant rewrite that justifies a new CodeProject publication.)

背景

与2005年编写的原始代码相比,此代码有几处改进

  1. 已为Code39条形码添加验证。代码检测到“条形码”(实际不存在)的几率大大降低。
  2. 提高了检测速度。原始项目中的主要问题是它使用了Bitmap.RotateFlip,而该函数速度很慢。
  3. 添加了EAN/UPC和Code128条形码支持。原始项目只能检测Code39条形码。
  4. 修复了qlipoth的项目和2004年由Benjamin Liedblad发布的图像条形码读取相关项目报告的一些错误。

使用代码

要打开解决方案,您需要Visual Studio 2008。但是我没有使用任何不兼容.NET 1.1的构造,因此实际代码也应该可以在Visual Studio 2003或2005中编译。

要使用该代码,请调用FullScanPageScanPage,并将包含图像的Windows Bitmap对象作为参数传递。随附的TestApp(用VB.NET编写)演示了基本用法。

Dim barcodes As New System.Collections.ArrayList
BarcodeImaging.FullScanPage(barcodes, Me.PictureBox1.Image, 100)
If barcodes.Count > 0 Then
  ' Found one or more barcodes ...

两个函数中的numscans参数表示应在图像的横向或纵向扫描多少个像素带。扫描次数越多,代码找到的条形码越多,但当然运行速度也会略慢。通常,50-100次扫描对于查找整页图像中的所有条形码来说就足够了。

FullScanPage和ScanPage之间的区别

FullScanPage始终水平和垂直扫描,并尝试检测所有支持的条形码类型。如果您知道输入的材料总是以相同的方向扫描,或者您不需要检测所有条形码类型,那么使用ScanPage可以使您的程序运行得更快。

public static void ScanPage(ref System.Collections.ArrayList CodesRead, 
       Bitmap bmp, int numscans, ScanDirection direction, BarcodeType types)

通过附加参数directiontypes,您可以微调条形码检测。

  • direction:可以是ScanDirection.VerticalScanDirection.Horizontal。使用Vertical检测竖向条形码,或在预期条形码旋转90度时使用Horizontal
  • types:传递BarcodeType.All以检测所有支持的条形码类型,或者您可以指定一种或多种特定条形码类型,如下所示。
    ScanPage(ref CodesRead, bmp, numscans, ScanDirection.Vertical,
             BarcodeType.Code39 | BarcodeType.Code128);

    支持的类型包括Code39、EAN和Code128。EAN阅读器还将检测UPC码。

关注点

  • EAN阅读器还可以读取经常在书籍和期刊上找到的2位或5位补充条形码。如图所示,补充条形码将作为一个单独的条形码字符串返回,以“S”开头。
  • Code128阅读器具有混合代码页支持。示例图像Code128test-CodeC.png中的序列号以Code C开头,但最后一个数字是以Code B添加的。
  • 与qlipoth和Liedblad的版本相比,该代码采用了一种更高级的方法来测量“窄条宽度”。这应该可以提高读取EAN和Code128的检测率。在Code39中,我们只需要区分窄条和宽条,但其他条形码类型使用四种不同的条形宽度。
  • 我添加了“条形码区域”的概念,以允许在同一扫描线上检测不同比例的条形码。在Code128test-CodeC.png中,这使得软件能够读取并排打印的序列号和UPC码。

    barcode zones

参考文献

在编写本项目时,我参考了以下资料:

  1. 用于实现EAN检测:维基百科上关于欧洲商品编码EAN-2EAN-5的文章。
  2. 用于实现Code 128:字符表校验位计算(来自code128barcodes.com),以及IDAutomation.com Inc.发布的条形码生成器,用于测试。

历史

  • 2009年10月5日:初版。
  • 2009年10月19日:改进了Code39检测,修复了错误。添加了 Alessandro Gubbiotti 提供的条形码检测类和COM接口的VB.NET版本。
© . All rights reserved.