环境: Win7 + MinGW
默认的Zbar for windows 中的DLL在windows不能支持中文,需要修改源码,然后重新编译,没有VS的工程,编译过程相当纠结。
1. 首先先安装 MinGW ,安装过程不详述,比较简单。
2. 将zbar源码放入到 msys/1.0/proj/下,默认路径为: C:\MinGW\msys\1.0\ ,proj是新建的目录。mingw会将1.0/目录下的内容当成是根目录。
3. 打开 MinGW 编译环境,如:
cd proj/zbar-0.10/ ,执行 ./configure --without-imagemagick。
肯定会出错,因为还有一些库环境没有配好。如 glib_2.22.2-1_win32.zip
pkg-config_0.23-3_win32.zip
gtk+-bundle-2.12.11.zip (可以不用配置)
./configure --enable-shared --without-jpeg --without-python --without-gtk --without-qt --without-imagemagick CPPFLAGS=-I/usr/include
禁用 jpeg python gtk qt imagemagick 库。
4. 不用按照着
http://sourceforge.net/apps/mediawiki/zbar/index.php?title=HOWTO:_Compile_with_MinGW_in_Windows 来做,可能是跟 MinGW版本有关。因为zbar依赖libiconv库,所以需要先编译libiconv库。
将 libiconv-1.14.tar.gz 解压到 proj/目录,进入mingw编译,顺利完成。
然后就可以编译zbar-0.10了,如果不编译iconv ,编译zbar肯定不过。
注意:os2/目录下有一个 iconv.def ,这个文件是过时的了,不能匹配最新的libconv-2.dll库,因此不能使用这个来生成lib,会导致运行时错误。
lib /def:iconv.def /machine:ix86
而应重新依据 libiconv-2.dll 生成,如:
然后修改这个文件,如:
一定是要在VS2008命令行中执行 lib 命令,否则出稀奇的错误,因为调用了别的lib。
至此,libiconv.lib 已经OK。
5. 因为目录存放在 proj/,所以需要更改 zbar的Makefile,指明库路径
以及头文件路径,如:
当然也可以不用做第5步,前提是在 ./configure 配置zbar之前,已经装好 libiconv库,这样会自动搜寻libiconv并写入到zbar的Makefile中,如:
注意: 编译过一次Zbar后,再次编译可能存在错误,提示 libzbar-rc.o : No such file or directory。这个是因为Makefile的Bug引起,需要手动去到zbar/目录删除 libzbar-rc.o 和 libzbar-rc.lo 才行。
这只是编译ZBAR库,要支持中文则还需要做修改,后续贴上。
源码下载:http://download.csdn.net/detail/liuyu60305002/6658241 (支持中文),含 libzbar-0.dll 这是已经编译好的。
调用方式,我这里采用 OpenCV 接口,ImageMagicK库效率太低了。给出一段调用代码如下:
int CSystemInfo::ProcessImage(const char *szPath,CODEBAR_INFO &info)
{
/* create a reader */
zbar_image_scanner_t *scanner = zbar_image_scanner_create();
/* configure the reader */
zbar_image_scanner_set_config(scanner, ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
/* obtain image data */
int width = 0, height = 0;
const void *raw = NULL;
//如果使用 Magick++ 库,只是在解析图片数据的位置有点差别
CvMat *cv_matrix = cvLoadImageM(szPath,CV_LOAD_IMAGE_GRAYSCALE);
width = cv_matrix->width;
height= cv_matrix->height;
raw = (char*)cv_matrix->data.ptr;
/* wrap image data */
zbar_image_t *image = zbar_image_create();
zbar_image_set_format(image, *(int*)"Y800");
zbar_image_set_size(image, width, height);
zbar_image_set_data(image, raw, width * height, zbar_image_free_data);
/* scan the image for barcodes */
int n = zbar_scan_image(scanner, image); //n == 0 is failed
/* extract results */
WCHAR *d;
int nd = 0;
const zbar_symbol_t *symbol = zbar_image_first_symbol(image);
for(; symbol; symbol = zbar_symbol_next(symbol))
{
/* do something useful with results */
zbar_symbol_type_t typ = zbar_symbol_get_type(symbol);
memcpy(info.type,zbar_get_symbol_name(typ),sizeof(info.type) - 1);
const char *data = zbar_symbol_get_data(symbol);
unsigned int len = zbar_symbol_get_data_length(symbol);
//printf("decoded %s symbol \"%s\"\n", zbar_get_symbol_name(typ), data);
nd = utf8_to_utf16((BYTE *)data,len,NULL,0); //utf-8 转成 unicode 需要多少字节
d = (WCHAR *)malloc((nd * 2) + 2);
utf8_to_utf16((BYTE *)data,len,d,nd); //utf-8 转成 unicode
memset(info.data,0,sizeof(info.data));
WideCharToMultiByte(CP_ACP,0,d,nd,(CHAR *)info.data,sizeof(info.data) - 1,NULL,NULL); //unicode 转 ascii
free(d);
}
return n;
}