ZBar 条码/二维码识别工具介绍及golang通过cmd调用ZBar从图片中批量识别二维码
ZBar 是一款开源的条码/二维码识别工具 ,核心专注于实时、高效的条码解码(识别),支持多平台(Linux、Windows、macOS)和多语言集成(C/C++、Python、Java、Golang 等),广泛用于嵌入式设备、桌面工具、工业扫码等场景,是条码识别领域的经典工具之一。
一、核心定位与核心能力
ZBar 的核心价值在于**"快速识别"**,尤其擅长处理实时图像流(如摄像头扫码)和静态图像,核心能力集中在以下两点:
1. 多格式条码解码(核心功能)
ZBar 支持主流一维码和二维码,覆盖绝大多数日常与工业场景,具体包括:
- 一维码(条形码):Code 128、Code 39、EAN-13、EAN-8、UPC-A、UPC-E、ITF、Codabar 等;
- 二维码:QR Code、Data Matrix(部分版本支持 Aztec Code)。
它能自动处理图像中的旋转、轻微变形,对清晰条码的识别速度快于许多纯 Go 库(如 gozxing)。
2. 多输入源支持
- 静态图像:识别本地图片文件(PNG、JPG、BMP 等);
- 实时流:对接摄像头(如 USB 摄像头、工业相机),支持实时扫码(需结合 OpenCV 等图像采集库);
- 灰度/彩色图像:自动处理彩色图像转灰度,无需额外预处理。
二、支持的平台与开发语言
ZBar 以 C 语言为核心实现,通过绑定库支持多语言,适配主流开发环境:
类别 | 具体支持 |
---|---|
操作系统 | Linux(原生支持)、Windows(需编译或使用预编译库)、macOS(Homebrew 可安装) |
开发语言 | C/C++(原生 API)、Python(pyzbar 库)、Java(zbarjni )、Ruby、Perl 等 |
嵌入式平台 | 树莓派、ARM 架构设备(需交叉编译,适合嵌入式扫码场景) |
三、常用使用方式
ZBar 有两种核心使用形态:命令行工具 (快速测试)和 编程库集成(开发应用),以下是典型示例:
1. 命令行工具(快速识别图片)
安装 ZBar 后,可直接通过命令行识别本地图片,无需写代码,适合快速验证条码有效性。
-
Linux/macOS 安装 :
Linux(Ubuntu/Debian):
sudo apt-get install zbar-tools
macOS(Homebrew):
brew install zbar
-
命令示例:
bash# 识别图片中的条码,输出内容和码制 zbarimg test_qrcode.png # 仅输出条码内容(忽略码制信息) zbarimg --raw test_barcode.jpg
-
输出示例:
rubyQR-Code:https://example.com scanned 1 barcode symbol from 1 image
2. 编程集成(以 Python 为例)
Python 中通过 pyzbar
库调用 ZBar,适合快速开发桌面或轻量后端应用,步骤简单:
-
安装依赖:
bash# 先安装 ZBar 系统库(见上文),再安装 Python 绑定 pip install pyzbar pillow # pillow 用于处理图像
-
代码示例(识别图片中的条码):
pythonfrom PIL import Image from pyzbar.pyzbar import decode # 1. 读取图片 img = Image.open("test_qrcode.png") # 2. 调用 ZBar 解码 results = decode(img) # 3. 解析结果 for result in results: # 获取条码内容(bytes 转字符串) content = result.data.decode("utf-8") # 获取码制(如 'QRCODE'、'CODE128') format = result.type print(f"码制: {format}, 内容: {content}")
3. 编程集成(以 C++ 为例,原生 API)
适合高性能场景(如工业扫码、实时流处理),直接调用 ZBar 核心 C API:
cpp
#include <zbar.h>
#include <opencv2/opencv.hpp> // 用于读取图像(可选,也可自行处理)
using namespace zbar;
using namespace cv;
int main() {
// 1. 初始化 ZBar 扫描器
ImageScanner scanner;
scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1); // 启用所有码制识别
// 2. 读取图像(用 OpenCV 读取为灰度图)
Mat img = imread("test_barcode.jpg", IMREAD_GRAYSCALE);
int width = img.cols;
int height = img.rows;
// 3. 转换为 ZBar 支持的 Image 格式
Image zbar_img(width, height, "Y800", img.data, width * height);
// 4. 扫描条码
int n = scanner.scan(zbar_img);
// 5. 输出结果
for (Image::SymbolIterator symbol = zbar_img.symbol_begin();
symbol != zbar_img.symbol_end(); ++symbol) {
printf("码制: %s, 内容: %s\n",
symbol->get_type_name(),
symbol->get_data().c_str());
}
// 释放资源
zbar_img.set_data(NULL, 0);
return 0;
}
-
编译命令 (需链接 ZBar 和 OpenCV 库):
bashg++ -o zbar_demo zbar_demo.cpp -lzbar `pkg-config --cflags --libs opencv4`
四、优缺点分析
优点 | 缺点 |
---|---|
1. 识别速度快,尤其适合实时流(摄像头)场景; | 1. 不支持条码编码(仅能解码,生成条码需搭配其他库); |
2. 对清晰条码的识别率高,抗旋转能力强; | 2. Windows 环境编译/安装较复杂(需依赖 Visual Studio 或预编译库); |
3. 轻量级,内存占用低,适合嵌入式设备; | 3. 对模糊、严重变形的条码容错率低于 ZXing(gozxing 基于 ZXing); |
4. 支持多语言绑定,开发灵活; | 4. 部分冷门码制(如 Aztec Code)支持不完善; |
五、典型应用场景
- 嵌入式扫码设备:树莓派 + 摄像头组成的低成本扫码器(如便利店收银、仓库盘点);
- 实时扫码工具:桌面端摄像头扫码软件(如二维码登录、商品条码查询);
- 工业自动化:生产线条码识别(需结合工业相机,要求快速响应);
- 批量图片处理:后端批量识别用户上传的条码图片(如物流单号录入)。
要不要我帮你整理一份 ZBar 环境搭建与快速入门指南,包含 Linux/macOS/Windows 三大平台的安装步骤、命令行常用指令,以及 Python/C++ 最简示例代码,帮你快速上手使用 ZBar?
六、在Golang使用ZBar工具识别图片中的二维码
ZBar是一个开源的条码识别工具,可以通过命令行使用。以下是通过Go调用ZBar命令行工具识别二维码的方法:
go
package main
import (
"fmt"
"os/exec"
"strings"
)
// ReadQRCodeWithZBar 使用ZBar工具识别图片中的二维码
// 参数:
// - imagePath: 图片路径
// - zbarPath: ZBar工具路径(如"zbarimg"或"ZBar/bin/zbarimg")
// 返回值:
// - []string: 识别到的二维码内容列表
// - error: 错误信息
func ReadQRCodeWithZBar(imagePath, zbarPath string) ([]string, error) {
// 构造ZBar命令
// -q 参数表示安静模式,只输出识别结果
cmd := exec.Command(zbarPath, "-q", imagePath)
// 执行命令并获取输出
output, err := cmd.Output()
if err != nil {
return nil, fmt.Errorf("执行ZBar命令失败: %v", err)
}
// 解析输出结果
var results []string
// 按行分割输出
lines := strings.Split(string(output), "\n")
for _, line := range lines {
// 跳过空行
if line == "" {
continue
}
// ZBar输出格式为"类型:内容",如"QR-Code:HelloWorld"
parts := strings.SplitN(line, ":", 2)
if len(parts) == 2 && parts[0] == "QR-Code" {
// 提取二维码内容
content := strings.TrimSpace(parts[1])
results = append(results, content)
fmt.Printf("ZBar识别到二维码: %s\n", content)
}
}
return results, nil
}
func main() {
// 示例使用
imagePath := "./output/page_001_150dpi.png" // 图片路径
zbarPath := "ZBar/bin/zbarimg" // ZBar工具路径
// 识别二维码
results, err := ReadQRCodeWithZBar(imagePath, zbarPath)
if err != nil {
fmt.Printf("识别失败: %v\n", err)
return
}
// 打印识别结果
fmt.Println("\n=== ZBar识别结果 ===")
for i, res := range results {
fmt.Printf("%d: %s\n", i+1, res)
}
}
构造ZBar命令
2. 使用`-q`参数启用安静模式,只输出识别结果
3. 解析ZBar输出的"类型:内容"格式结果
4. 提取二维码内容并返回