Windows 系统上使用 ZBar
发布于 2022-01-02
ZBar 是个开源的 C 语言识别 条形码、二维码的库。同事对比发现它的识别准确率比另外一个库 ZXing 要好。
ZBar本身是在 Linux/Unix 平台上开发的,网上有关介绍 ZBar 的使用是在 Android/iOS 平台上的比较多,Windows上的介绍比较少,故写篇博客总结一下。
集成 ZBar 库
因为 ZBar 是在 Linux/Unix 平台上开发的,因此想通过源码移植的方式使用难度比较大。在 Windows 上比较方便的集成 ZBar 库的方式是直接使用官方提供给 Windows 平台已经编译好的 dll。
在 ZBar download 页面可以下载到已经编译好的 Windows Installer。下载安装后就在安装目录里面找到集成 ZBar 所需要的 头文件、lib、dll。
Zbar 支持的格式
Zbar 支持识别图片的格式可以从 convert.c
文件里找到定义。格式不是很多,像比较通用的 png、jpg 格式,还需要额外的库支持。
官方 demo
ZBar 库源码里面 examples 目录一个 scan_image 的例子。另外还有 zbarcam、zbarimg 两个小工具。zbarcam 是从摄像头中获取图像数据来识别条形码、二维码。zbarimg 是读取磁盘图片文件来识别条形码、二维码。这个两个工具的源码也在库中。
集成 ImageMagick
从 zbarimg 这个工具的源码可以看到,为了支持多种图片格式,zbarimg 引入了 ImageMagick 这个图片处理库支持,把其他格式图片转换成 Zbar 内部支持的 GREY 格式。
同样的,ImageMagick 也是基于 Linux/Unix 平台上开发的,也可以安装官方预编译好的二进制文件到 Windoows 平台。
在 ImageMagick download 页面可以下载到已经编译好的 Windows Binary Release。下载安装后就在安装目录里面找到集成 ImageMagick 所需要的 头文件、lib、dll。
使用 ImageMagick 之前,需要先在代码初始化一下 ImageMagick 的路径:
Magick::InitializeMagick(image_magick_bin_path);
新的版本,如果是通过安装的,dll内部是从注册表中定位ImageMagick 的路径。
识别图片
虽然 Zbar 是 C 语言实现的,但是它处理提供 C 接口,还提供了更方便的 C++ 接口。
// 把原始的图片数据构造成 Magick::Blob 类型
Magick::Blob blob(image_data, image_data_length);
// 通过 Magick::Blob 构造 Magick::Image
Magick::Image image(blob);
// 获得图片的宽和高
size_t width = image.columns();
size_t height = image.rows();
// 把原始图片转换成 Zbar 内部支持的 gray 格式
Magick::Blob gray_blob;
image.modifyImage();
image.write(&gray_blob, "GRAY", 8);
const void *gray_blob_data = gray_blob.data();
size_t gray_image_size = width * height;
// 构造成 zbar::Image
zbar::Image gray_image(width, height, "Y800", gray_blob_data,
gray_image_size);
// 通过 zbar::ImageScanner 对象识别图片
zbar::ImageScanner scanner;
int scan_result = scanner.scan(gray_image);
if (scan_result <= 0) {
return false;
}
// 读取识别后的结果
for (zbar::Image::SymbolIterator symbol = gray_image.symbol_begin();
symbol != gray_image.symbol_end(); ++symbol) {
cout << "decoded " << symbol->get_type_name()
<< " symbol \"" << symbol->get_data() << '"' << endl;
}
gray_image.set_data(NULL, 0);