| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛 | 
共有 1325 人关注过本帖
标题:又发现一个条码解码神器zbar-0.10
只看楼主 加入收藏
sam_jiang
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:14
帖 子:1272
专家分:1687
注 册:2021-10-13
收藏
 问题点数:0 回复次数:13 
又发现一个条码解码神器zbar-0.10
我对条码解决方案情有独钟,哈哈,又发现一个条码解码神器zbar-0.10

附上安装包:
zbar-0.10-setup.zip (3.03 MB)

这是可独立运行的程序,可以识别图片中的条码以及视频中的条码。

我对它的dll文件进行了分析(它是开源的,我这不算侵犯版权),网上查了很多资料,获得一手的函数资料。

把declare声明函数先发出来,后续再把如何调用的范例也发上来,供大家研究。
deepseek很笨的,字符型指针,void类型数据不知道怎么声明,告诉它几次了,下次问它又忘记。。。
让它给我加上注释倒是很完整,清晰,这个必须点赞。

程序代码:
*------------------------------------------------------------*
* ZBar DLL 函数声明 - 修正版(所有指针为INTEGER)
*------------------------------------------------------------*

* 基础函数
DECLARE INTEGER zbar_version IN libzbar-0.dll ;
    INTEGER @major, INTEGER @minor

* 图像扫描器
DECLARE INTEGER zbar_image_scanner_create IN libzbar-0.dll
DECLARE zbar_image_scanner_destroy IN libzbar-0.dll ;
    INTEGER scanner
DECLARE INTEGER zbar_image_scanner_set_config IN libzbar-0.dll ;
    INTEGER scanner, INTEGER symbology, INTEGER config, INTEGER value
DECLARE zbar_image_scanner_enable_cache IN libzbar-0.dll ;
    INTEGER scanner, INTEGER enable
DECLARE INTEGER zbar_image_scanner_get_results IN libzbar-0.dll ;
    INTEGER scanner

* 图像对象
DECLARE INTEGER zbar_image_create IN libzbar-0.dll
DECLARE zbar_image_destroy IN libzbar-0.dll ;
    INTEGER image
DECLARE zbar_image_set_format IN libzbar-0.dll ;
    INTEGER image, INTEGER format
DECLARE zbar_image_set_size IN libzbar-0.dll ;
    INTEGER image, INTEGER width, INTEGER height
DECLARE zbar_image_set_data IN libzbar-0.dll ;
    INTEGER image, INTEGER data, INTEGER data_len, INTEGER cleanup
DECLARE INTEGER zbar_image_get_symbols IN libzbar-0.dll ;
    INTEGER image

* 扫描函数
DECLARE INTEGER zbar_scan_image IN libzbar-0.dll ;
    INTEGER scanner, INTEGER image

* 符号操作 - 所有返回字符串的改为INTEGER
DECLARE INTEGER zbar_symbol_set_first_symbol IN libzbar-0.dll ;
    INTEGER symbol_set
DECLARE INTEGER zbar_symbol_get_type IN libzbar-0.dll ;
    INTEGER symbol
DECLARE INTEGER zbar_get_symbol_name IN libzbar-0.dll ;
    INTEGER symbol_type    && 返回char*指针
DECLARE INTEGER zbar_symbol_get_data IN libzbar-0.dll ;
    INTEGER symbol         && 返回char*指针
DECLARE INTEGER zbar_symbol_get_data_length IN libzbar-0.dll ;
    INTEGER symbol
DECLARE INTEGER zbar_symbol_next IN libzbar-0.dll ;
    INTEGER symbol
DECLARE INTEGER zbar_symbol_get_loc_size IN libzbar-0.dll ;
    INTEGER symbol
DECLARE INTEGER zbar_symbol_get_loc_x IN libzbar-0.dll ;
    INTEGER symbol, INTEGER index
DECLARE INTEGER zbar_symbol_get_loc_y IN libzbar-0.dll ;
    INTEGER symbol, INTEGER index

* 错误处理
DECLARE INTEGER _zbar_error_string IN libzbar-0.dll ;
    INTEGER object, INTEGER verbosity    && 返回char*指针
DECLARE INTEGER _zbar_get_error_code IN libzbar-0.dll ;
    INTEGER object

* 符号集操作
DECLARE INTEGER zbar_symbol_set_ref IN libzbar-0.dll ;
    INTEGER symbols, INTEGER refs
DECLARE INTEGER zbar_symbol_set_get_size IN libzbar-0.dll ;
    INTEGER symbols

* 其他辅助函数
DECLARE INTEGER zbar_symbol_ref IN libzbar-0.dll ;
    INTEGER symbol, INTEGER refs
DECLARE INTEGER zbar_symbol_first_component IN libzbar-0.dll ;
    INTEGER symbol
DECLARE INTEGER zbar_symbol_get_components IN libzbar-0.dll ;
    INTEGER symbol
    
* 符号类型常量
#define ZBAR_NONE       0
#define ZBAR_PARTIAL    1
#define ZBAR_EAN8       8
#define ZBAR_UPCE       9
#define ZBAR_ISBN10     10
#define ZBAR_UPCA       12
#define ZBAR_EAN13      13
#define ZBAR_ISBN13     14
#define ZBAR_I25        25
#define ZBAR_CODE39     39
#define ZBAR_PDF417     57
#define ZBAR_QRCODE     64
#define ZBAR_CODE128    128

* 配置常量
#define ZBAR_CFG_ENABLE         0
#define ZBAR_CFG_ADD_CHECK      1
#define ZBAR_CFG_EMIT_CHECK     2
#define ZBAR_CFG_ASCII          3
#define ZBAR_CFG_MIN_LEN        0x20
#define ZBAR_CFG_MAX_LEN        0x21
#define ZBAR_CFG_POSITION       0x80
#define ZBAR_CFG_X_DENSITY      0x100
#define ZBAR_CFG_Y_DENSITY      0x101

* 四字符码
#define FOURCC_Y800     0x30303859  && 'Y800'
#define FOURCC_GRAY     0x59415247  && 'GRAY'    


收到的鲜花
  • kangss 于 2026-09-26 12:23 送鲜花  1朵   附言:必须点赞
搜索更多相关主题的帖子: DLL INTEGER 条码 define symbol 
2026-09-25 23:26
星光悠蓝
Rank: 9Rank: 9Rank: 9
来 自:山水甲天下
等 级:贵宾
威 望:52
帖 子:547
专家分:1331
注 册:2010-1-11
收藏
 得分:0 
2026-09-26 13:21
schtg
Rank: 13Rank: 13Rank: 13Rank: 13
来 自:USA
等 级:贵宾
威 望:67
帖 子:2792
专家分:4967
注 册:2012-2-29
收藏
 得分:0 
2026-09-26 16:36
seasoners
Rank: 2
等 级:论坛游民
帖 子:127
专家分:22
注 册:2013-12-15
收藏
 得分:0 
期待范例,谢谢Sam_Jiang
2026-09-29 08:59
sam_jiang
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:14
帖 子:1272
专家分:1687
注 册:2021-10-13
收藏
 得分:0 
先确保当前dll版本是0.10
代码如下:
如果不是0.10版,调用可能出意外。。。
程序代码:
do zbardeclare &&上面的申明函数
nmajor=0
nminor=0
?zbar_version(@nmajor,@nminor)
?nmajor,nminor &&0,10



[此贴子已经被作者于2026-10-1 21:44编辑过]

2026-10-01 20:23
sam_jiang
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:14
帖 子:1272
专家分:1687
注 册:2021-10-13
收藏
 得分:0 
识别条码程序代码如下:
程序代码:
*------------------------------------------------------------*
* 扫描图片中的二维码/条形码 - 需要用到我开发的ImageConverter类
* 参数:tcImageFile [color=#808080]- 图片文件路径[/color]
* 返回:识别到的符号数量,[color=#808080]-1表示错误[/color]
*------------------------------------------------------------*
FUNCTION ScanBarcode(tcImageFile)
    LOCAL loConverter, lnScanner, lnImage, lnResult
    LOCAL lnSymbolSet, lnSymbol, lnType
    LOCAL lnTypeNamePtr, lcTypeName
    LOCAL lnDataPtr, lcData
    LOCAL lnDataLen, lnLocSize, i
    LOCAL lnResultCount
    LOCAL lcGrayData, lnWidth, lnHeight
    LOCAL lcRGB24, lcARGB32, lnDataAddr
    
    * 1. 创建ImageConverter并加载图片
    loConverter = CREATEOBJECT("ImageConverter")
    IF !loConverter.LoadImage(tcImageFile)
        MESSAGEBOX("无法加载图片:" + tcImageFile, 16, "错误")
        loConverter = NULL
        RETURN -1
    ENDIF
    
    * 2. 获取图像尺寸
    lnWidth = loConverter.GetImageWidth()
    lnHeight = loConverter.GetImageHeight()
    
    IF lnWidth <= 0 OR lnHeight <= 0
        MESSAGEBOX("无效的图像尺寸", 16, "错误")
        loConverter = NULL
        RETURN -1
    ENDIF
    
    * 3. 转换为灰度图(直接修改图像对象)
    IF !loConverter.ToGray()
        MESSAGEBOX("灰度转换失败", 16, "错误")
        loConverter = NULL
        RETURN -1
    ENDIF
    
    * 4. 获取灰度图数据
    lcGrayData = ""
    
    * 尝试用 GetRawData24()
    lcRGB24 = loConverter.GetRawData24()
    IF !EMPTY(lcRGB24)
        lcGrayData = ExtractRFromRGB24(lcRGB24)
    ELSE
        * 如果GetRawData24失败,改用GetRawData
        lcARGB32 = loConverter.GetRawData()
        IF !EMPTY(lcARGB32)
            lcGrayData = ExtractRFromARGB32(lcARGB32)
        ENDIF
    ENDIF
    
    IF EMPTY(lcGrayData)
        MESSAGEBOX("获取灰度数据失败", 16, "错误")
        loConverter = NULL
        RETURN -1
    ENDIF
    
    * 5. 创建扫描器
    lnScanner = zbar_image_scanner_create()
    IF lnScanner = 0
        MESSAGEBOX("创建扫描器失败!", 16, "错误")
        loConverter = NULL
        RETURN -1
    ENDIF
    
    * 6. 配置扫描器 - 启用所有符号类型
    = zbar_image_scanner_set_config(lnScanner, 0, 0, 1)
    = zbar_image_scanner_enable_cache(lnScanner, 0)
    
    * 7. 创建ZBar图像对象
    lnImage = zbar_image_create()
    IF lnImage = 0
        = zbar_image_scanner_destroy(lnScanner)
        MESSAGEBOX("创建图像对象失败!", 16, "错误")
        loConverter = NULL
        RETURN -1
    ENDIF
    
    * 8. 设置图像参数 - Y800格式(8位灰度)
    lnDataAddr = 0
    
    DECLARE INTEGER GlobalAlloc IN kernel32 INTEGER uFlags, INTEGER dwBytes
    DECLARE INTEGER GlobalFree IN kernel32 INTEGER hMem
    
    lnDataAddr = GlobalAlloc(0, LEN(lcGrayData))
    IF lnDataAddr = 0
        MESSAGEBOX("分配内存失败!", 16, "错误")
        = zbar_image_scanner_destroy(lnScanner)
        loConverter = NULL
        RETURN -1
    ENDIF
    
    * 将数据复制到分配的内存
    = StrToMem(lnDataAddr, lcGrayData, LEN(lcGrayData))
    
    * 设置图像数据
    = zbar_image_set_format(lnImage, 0x30303859)  && 'Y800'
    = zbar_image_set_size(lnImage, lnWidth, lnHeight)
    = zbar_image_set_data(lnImage, lnDataAddr, LEN(lcGrayData), 0)
    
    * 9. 执行扫描
    lnResult = zbar_scan_image(lnScanner, lnImage)
    
    * 释放分配的内存
    = GlobalFree(lnDataAddr)
    
    * 10. 输出结果到屏幕
    lnResultCount = 0
    
    ? "========================================"
    ? "扫描文件: " + tcImageFile
    ? "图像尺寸: " + TRANSFORM(lnWidth) + " x " + TRANSFORM(lnHeight)
    ? "扫描结果: " + TRANSFORM(lnResult) + " 个符号"
    ? "========================================"
    
    IF lnResult > 0
        lnSymbolSet = zbar_image_get_symbols(lnImage)
        IF lnSymbolSet != 0
            lnSymbol = zbar_symbol_set_first_symbol(lnSymbolSet)
            DO WHILE lnSymbol != 0
                * 获取类型
                lnType = zbar_symbol_get_type(lnSymbol)
                lnTypeNamePtr = zbar_get_symbol_name(lnType)
                lcTypeName = PtrToString(lnTypeNamePtr)
                
                * 获取数据
                lnDataPtr = zbar_symbol_get_data(lnSymbol)
                lnDataLen = zbar_symbol_get_data_length(lnSymbol)
                lcData = PtrToStringLen(lnDataPtr, lnDataLen)
                
                * 获取位置信息
                lnLocSize = zbar_symbol_get_loc_size(lnSymbol)
                
                lnResultCount = lnResultCount + 1
                
                * 屏幕输出
                ? "----------------------------------------"
                ? "符号 #" + TRANSFORM(lnResultCount)
                ? "  类型     : " + lcTypeName
                ? "  数据长度 : " + TRANSFORM(lnDataLen)
                ? "  定位点数 : " + TRANSFORM(lnLocSize)
                ? "  数据内容 :"
                ? "  " + lcData
                
                * 下一个符号
                lnSymbol = zbar_symbol_next(lnSymbol)
            ENDDO
        ENDIF
    ELSE
        ? "未识别到任何二维码/条形码"
    ENDIF
    
    ? "========================================"
    
    * 11. 清理资源
    = zbar_image_destroy(lnImage)
    = zbar_image_scanner_destroy(lnScanner)
    loConverter = NULL
    
    RETURN lnResultCount
ENDFUNC

*------------------------------------------------------------*
* 从24位RGB数据提取R通道作为灰度 (BGR顺序,每3字节一个像素)
*------------------------------------------------------------*
FUNCTION ExtractRFromRGB24(tcRGB24)
    LOCAL lnLen, lnPixelCount, i, lnPos, lcResult
    
    lnLen = LEN(tcRGB24)
    IF lnLen = 0 OR lnLen % 3 != 0
        RETURN ""
    ENDIF
    
    lnPixelCount = INT(lnLen / 3)
    lcResult = SPACE(lnPixelCount)
    
    FOR i = 0 TO lnPixelCount - 1
        lnPos = i * 3 + 1
        lcResult = STUFF(lcResult, i + 1, 1, SUBSTR(tcRGB24, lnPos + 2, 1))
    ENDFOR
    
    RETURN lcResult
ENDFUNC

*------------------------------------------------------------*
* 从32位ARGB数据提取R通道作为灰度 (BGRA顺序,每4字节一个像素)
*------------------------------------------------------------*
FUNCTION ExtractRFromARGB32(tcARGB32)
    LOCAL lnLen, lnPixelCount, i, lnPos, lcResult
    
    lnLen = LEN(tcARGB32)
    IF lnLen = 0 OR lnLen % 4 != 0
        RETURN ""
    ENDIF
    
    lnPixelCount = INT(lnLen / 4)
    lcResult = SPACE(lnPixelCount)
    
    FOR i = 0 TO lnPixelCount - 1
        lnPos = i * 4 + 1
        lcResult = STUFF(lcResult, i + 1, 1, SUBSTR(tcARGB32, lnPos + 2, 1))
    ENDFOR
    
    RETURN lcResult
ENDFUNC
2026-10-01 21:23
schtg
Rank: 13Rank: 13Rank: 13Rank: 13
来 自:USA
等 级:贵宾
威 望:67
帖 子:2792
专家分:4967
注 册:2012-2-29
收藏
 得分:0 
2026-10-02 05:27
sam_jiang
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:14
帖 子:1272
专家分:1687
注 册:2021-10-13
收藏
 得分:0 
逐步测试视频采集条码的程序testcamera作用,打开摄像头,初始化,关闭。。。
程序代码:
*!*------------------------------------------------------------------------*!*
*!* testcamera.prg                                                                        *!*
*!* 逐步测试这个dll的视频采集条码功能                                           *!*
*!*------------------------------------------------------------------------*!*
CLEAR

* [color=#008080]---- 声明 ----
[/color]DECLARE INTEGER zbar_processor_create IN libzbar-0.dll INTEGER
DECLARE INTEGER zbar_processor_init IN libzbar-0.dll ;
    INTEGER processor, STRING video_device, INTEGER enable_display
DECLARE INTEGER zbar_processor_destroy IN libzbar-0.dll INTEGER

* 顺便声明错误信息函数,方便排查
DECLARE INTEGER zbar_processor_error_string IN libzbar-0.dll ;
    INTEGER processor, INTEGER verbosity
DECLARE INTEGER zbar_processor_get_error_code IN libzbar-0.dll INTEGER

* [color=#008080]---- 1. 创建 processor ----
[/color]LOCAL lnProc, lnRet
lnProc = zbar_processor_create(1)   && 1 = 使用线程
? "zbar_processor_create 返回: " + TRANSFORM(lnProc)

IF lnProc = 0
    ? "创建失败,无法继续"
    RETURN
ENDIF

* [color=#008080]---- 2. 初始化(video_device = NULL 表示默认摄像头,enable_display = 0)----
[/color]lnRet = zbar_processor_init(lnProc, 0, 0)
? "zbar_processor_init 返回: " + TRANSFORM(lnRet)

IF lnRet != 0
    ? "初始化失败!错误码: " + TRANSFORM(zbar_processor_get_error_code(lnProc))
    * 尝试读取错误字符串(如果存在)
    * ? "错误信息: " + PtrToString(zbar_processor_error_string(lnProc, 1))
ELSE
    ? "初始化成功!摄像头已打开"
ENDIF

* [color=#008080]---- 3. 销毁 ----
[/color]= zbar_processor_destroy(lnProc)
? "zbar_processor_destroy 完成"
? "==== 测试结束 ===="


7 天前 22:17
sam_jiang
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:14
帖 子:1272
专家分:1687
注 册:2021-10-13
收藏
 得分:0 
additionalfunction.prg
程序代码:
*------------------------------------------------------------*
* 从内存指针读取字符串
* 参数:lnPtr [color=#808080]- 字符串指针[/color]
* 返回:字符串内容
*------------------------------------------------------------*
FUNCTION PtrToString(lnPtr)
    LOCAL lcResult, lnChar, i
    
    IF lnPtr = 0
        RETURN ""
    ENDIF
    
    * 逐字节读取直到遇到空字符
    lcResult = ""
    i = 0
    DO WHILE .T.
        lnChar = Sys(2600, lnPtr + i, 1)  && 读取1个字节
        IF lnChar = CHR(0)
            EXIT
        ENDIF
        lcResult = lcResult + lnChar
        i = i + 1
    ENDDO
    
    RETURN lcResult
ENDFUNC

*------------------------------------------------------------*
* 更高效的字符串读取(如果字符串长度已知)
*------------------------------------------------------------*
FUNCTION PtrToStringLen(lnPtr, lnLength)
    IF lnPtr = 0 OR lnLength = 0
        RETURN ""
    ENDIF
    RETURN Sys(2600, lnPtr, lnLength)
ENDFUNC

*------------------------------------------------------------*
* 获取ZBar错误信息
*------------------------------------------------------------*
FUNCTION GetZBarError()
    LOCAL lnErrorPtr, lcError
    lnErrorPtr = _zbar_error_string(0, 1)
    IF lnErrorPtr = 0
        RETURN "无错误信息"
    ENDIF
    RETURN PtrToString(lnErrorPtr)
ENDFUNC

*------------------------------------------------------------*
* 测试DLL是否加载成功
*------------------------------------------------------------*
FUNCTION TestZBar()
    LOCAL lnMajor, lnMinor, lnResult
    lnMajor = 0
    lnMinor = 0
    lnResult = zbar_version(@lnMajor, @lnMinor)
    IF lnResult = 0
        ? "ZBar DLL加载成功!版本:", lnMajor, ".", lnMinor
        RETURN .T.
    ELSE
        ? "ZBar DLL加载失败!错误代码:", lnResult
        ? GetZBarError()
        RETURN .F.
    ENDIF
ENDFUNC

*------------------------------------------------------------*
* 获取符号类型名称(通过指针)
*------------------------------------------------------------*
FUNCTION GetSymbolTypeName(lnType)
    LOCAL lnPtr
    lnPtr = zbar_get_symbol_name(lnType)
    RETURN PtrToString(lnPtr)
ENDFUNC

*------------------------------------------------------------*
* 从二进制数据创建ZBar图像(无需ImageConverter)
*------------------------------------------------------------*
FUNCTION CreateZBarImageFromData(tcData, tnWidth, tnHeight)
    LOCAL lnImage
    lnImage = zbar_image_create()
    IF lnImage != 0
        = zbar_image_set_format(lnImage, 0x30303859)  && Y800
        = zbar_image_set_size(lnImage, tnWidth, tnHeight)
        = zbar_image_set_data(lnImage, @tcData, LEN(tcData), 0)
    ENDIF
    RETURN lnImage
ENDFUNC
7 天前 22:26
sam_jiang
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:14
帖 子:1272
专家分:1687
注 册:2021-10-13
收藏
 得分:0 
启动视频流。。。
程序代码:
*!*------------------------------------------------------------------------*!*
*!* lunchcamera.prg                                                        *!*
*!* 逐步测试这个dll的视频采集条码功能                                      *!*
*!* 启动视频流                                                             *!*
*!*------------------------------------------------------------------------*!*
CLEAR
CLEAR DLLS

DECLARE INTEGER zbar_processor_create IN libzbar-0.dll INTEGER
DECLARE INTEGER zbar_processor_init IN libzbar-0.dll ;
    INTEGER processor, STRING video_device, INTEGER enable_display
DECLARE INTEGER zbar_processor_destroy IN libzbar-0.dll INTEGER
DECLARE INTEGER zbar_processor_set_config IN libzbar-0.dll ;
    INTEGER processor, INTEGER symbology, INTEGER config, INTEGER value
DECLARE INTEGER zbar_processor_set_active IN libzbar-0.dll ;
    INTEGER processor, INTEGER active

LOCAL lnProc, lnRet

lnProc = zbar_processor_create(1)
? "create: " + TRANSFORM(lnProc)

lnRet = zbar_processor_init(lnProc, 0, 0)
? "init: " + TRANSFORM(lnRet)

IF lnRet = 0
    * 启用所有符号类型
    lnRet = zbar_processor_set_config(lnProc, 0, 0, 1)
    ? "set_config: " + TRANSFORM(lnRet)

    * 启动视频流(后台线程开始扫描)
    lnRet = zbar_processor_set_active(lnProc, 1)
    ? "set_active: " + TRANSFORM(lnRet)

    * 等 5 秒,让后台线程跑一会儿
    INKEY(5)

    * 停止视频流
    = zbar_processor_set_active(lnProc, 0)
    ? "已停止视频流"
ENDIF

= zbar_processor_destroy(lnProc)
? "destroy 完成"
7 天前 22:33
快速回复:又发现一个条码解码神器zbar-0.10
数据加载中...
 
   
关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019580 second(s), 11 queries.
Copyright©2004-2026, BCCN.NET, All Rights Reserved