Android-从0开始集成编译zbar到能光速扫出二维码

前几天在群里吹牛逼,说到微信的扫码怎么怎么吊.怎么怎么厉害..

当时一阵不服气.决定自己封装扫码器,后来搜了下,市场上大多数都是zxing和zbar.然后c语言我又不会,只能去封装zxing.

后来工作没事情做,正好抽时间补了一下,把zbar给封装一编,做出一个最简单的扫码器.

微信扫码是真的快,爱奇艺也是,不过我反编译看了下,他们用的满多jni还有都是zxing.

以下是我封装zbar地址,贼简单.具体可以看下demo

https://github.com/ccx1/EZbar


编译zbar流程

编译libiconv

首先我们需要了解一下,zbar编译需要啥.我看了严大的博客.在结合自己的,一步一步实现编译集成

Zbar的官网可以下载已经编译好的so和jar,不过so库版本只有armeabiarmeabi-v7ax86平台

所以我决定,自己来

先下载一波zbar的源码

https://github.com/ZBar/ZBar

然后需要下载libiconv,下载最新版本就好了,我下载的是最新的1.7版本,反正,蛮好用.

https://ftp.gnu.org/pub/gnu/libiconv/

然后准备工程完成之后呢,先解压libiconv.

然后进入到文件夹中.执行命令行.

注意:这里编译需要linux系统,.我是mac,我编译了半天.一直出错.=-=,这里非常关键,如果没有权限.sudo chmod 777 configure

./configure

然后编译完成之后执行

make

这就编译好了,然后从linux把这个拿下里,我拿下来的时候是通过压缩,然后sz命令拿下来的

这时候libiconv已经编译好了.

然后修改一些参数

打开libiconv

libiconv-1.7 -> libcharset -> config.h

第43行的样子,把最后位的1改成0

原先:

/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
#define HAVE_LANGINFO_CODESET 1

改完后:

/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
#define HAVE_LANGINFO_CODESET 0

第二步打开

libiconv-1.7 -> libcharset -> lib -> localcharset.c

然后

找到int c; 在get_charset_aliases()方法中.全局搜索也可以

修改成

libiconv暂时告一段落.

Zbar编译

在andorid工程的src/main目录下创建一个jni文件夹.然后.把刚刚编译的libiconv,以及下载过来的zbar组件拿过来.

1. 把libiconv拿过来放到jni目录下面

2. zbar/include 这个include整个拿进去.

3. zbarjni.c 放到刚刚创建的jni目录下,这个文件在zbar/java目录下面.

4. 把zbar core库拿过来,也就是zbar/zbar目录放到jni下面

5. 在zbar目录下面的Android.mk、Applicaiton.mk、config.h从zbar\android\jni 拿到项目目录jni下面

目录下就这些文件,都放在jni目录下面.

然后接着开始修改Android.mk.先是修改一波路径

首先介绍一波原版,需要修改libiconv的LOCAL_PATH以及所有跟路径有关的东西

zbar的地方也是修改所有路径,

#
# Android NDK makefile 
#
# build - <ndk path>/ndk-build ICONV_SRC=<iconv library src> 
# clean -  <ndk path>/ndk-build clean
#
MY_LOCAL_PATH := $(call my-dir)

# libiconv 这边是编译libiconv
include $(CLEAR_VARS)
LOCAL_PATH := $(ICONV_SRC)

LOCAL_MODULE := libiconv

LOCAL_CFLAGS := \
    -Wno-multichar \
    -D_ANDROID \
    -DLIBDIR="c" \
    -DBUILDING_LIBICONV \
    -DBUILDING_LIBCHARSET \
    -DIN_LIBRARY

LOCAL_SRC_FILES := \
	lib/iconv.c \
	libcharset/lib/localcharset.c \
	lib/relocatable.c

LOCAL_C_INCLUDES := \
	$(ICONV_SRC)/include \
	$(ICONV_SRC)/libcharset \
	$(ICONV_SRC)/libcharset/include

include $(BUILD_SHARED_LIBRARY)

LOCAL_LDLIBS := -llog -lcharset

# libzbarjni 编译zbar
include $(CLEAR_VARS)

LOCAL_PATH := $(MY_LOCAL_PATH)
LOCAL_MODULE := zbarjni
LOCAL_SRC_FILES := ../../java/zbarjni.c \
		   ../../zbar/img_scanner.c \
		   ../../zbar/decoder.c \
		   ../../zbar/image.c \
		   ../../zbar/symbol.c \
		   ../../zbar/convert.c \
		   ../../zbar/config.c \
		   ../../zbar/scanner.c \
		   ../../zbar/error.c \
		   ../../zbar/refcnt.c \
		   ../../zbar/video.c \
		   ../../zbar/video/null.c \
		   ../../zbar/decoder/code128.c \
		   ../../zbar/decoder/code39.c \
		   ../../zbar/decoder/code93.c \
		   ../../zbar/decoder/codabar.c \
		   ../../zbar/decoder/databar.c \
		   ../../zbar/decoder/ean.c \
		   ../../zbar/decoder/i25.c \
		   ../../zbar/decoder/qr_finder.c \
		   ../../zbar/qrcode/bch15_5.c \
		   ../../zbar/qrcode/binarize.c \
		   ../../zbar/qrcode/isaac.c \
		   ../../zbar/qrcode/qrdec.c \
		   ../../zbar/qrcode/qrdectxt.c \
		   ../../zbar/qrcode/rs.c \
		   ../../zbar/qrcode/util.c

LOCAL_C_INCLUDES := ../include \
		    ../zbar \
		    $(ICONV_SRC)/include 

LOCAL_SHARED_LIBRARIES := libiconv

include $(BUILD_SHARED_LIBRARY)

改完之后.

 

#
# Android NDK makefile
#
# build - <ndk path>/ndk-build ICONV_SRC=<iconv library src>
# clean -  <ndk path>/ndk-build clean
#
MY_LOCAL_PATH := $(call my-dir)

# libiconv
include $(CLEAR_VARS)
LOCAL_PATH := $(MY_LOCAL_PATH)
LOCAL_MODULE := libiconv
LOCAL_CFLAGS := \
    -Wno-multichar \
    -D_ANDROID \
    -DLIBDIR="c" \
    -DBUILDING_LIBICONV \
    -DBUILDING_LIBCHARSET \
    -DIN_LIBRARY

LOCAL_SRC_FILES := \
    libiconv-1.7/lib/iconv.c \
    libiconv-1.7/libcharset/lib/localcharset.c

LOCAL_C_INCLUDES := \
    $(LOCAL_PATH)/libiconv-1.7/include \
    $(LOCAL_PATH)/libiconv-1.7/libcharset \
    $(LOCAL_PATH)/libiconv-1.7/libcharset/include

include $(BUILD_SHARED_LIBRARY)

LOCAL_LDLIBS := -llog -lcharset

# -----------------------------------------------------

# libzbarjni
include $(CLEAR_VARS)
LOCAL_PATH := $(MY_LOCAL_PATH)
LOCAL_MODULE := zbarjni
LOCAL_SRC_FILES := \
            zbarjni.c \
            zbar/img_scanner.c \
            zbar/decoder.c \
            zbar/image.c \
            zbar/symbol.c \
            zbar/convert.c \
            zbar/config.c \
            zbar/scanner.c \
            zbar/error.c \
            zbar/refcnt.c \
            zbar/video.c \
            zbar/video/null.c \
            zbar/decoder/code128.c \
            zbar/decoder/code39.c \
            zbar/decoder/code93.c \
            zbar/decoder/codabar.c \
            zbar/decoder/databar.c \
            zbar/decoder/ean.c \
            zbar/decoder/i25.c \
            zbar/decoder/qr_finder.c \
            zbar/qrcode/bch15_5.c \
            zbar/qrcode/binarize.c \
            zbar/qrcode/isaac.c \
            zbar/qrcode/qrdec.c \
            zbar/qrcode/qrdectxt.c \
            zbar/qrcode/rs.c \
            zbar/qrcode/util.c

LOCAL_C_INCLUDES := \
            $(LOCAL_PATH)/include \
            $(LOCAL_PATH)/zbar \
            $(LOCAL_PATH)/libiconv-1.7/include

LOCAL_SHARED_LIBRARIES := libiconv

include $(BUILD_SHARED_LIBRARY)

然后开始修改Applicaiton.mk.

这个里面涉及到了你需要产生哪写.so库.

我直接塞了一个all进去.全部生成

原版:

APP_ABI := armeabi armeabi-v7a x86

修改后

APP_ABI := all

终于准备工作做完了....

开始编译.

进入到jni目录.

也就是src/main/jni目录下.然后输入

ndk-build

如果没有ndk,以及没有配ndk的环境.会报错.下载完成需要配个环境变量

ndk下载地址

然后输入命令,你的目录下会产生一个obj目录,一个lib目录,lib目录就是我们要找的.

然后拷贝lib目录下的东西,放到libs下面,也就是以下这些,.

然后需要在build.gradle里面配置,这里一定要这么做.


    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }

然后把zbar/java的net文件夹拷贝出来,放到src/main/java下.

包名都不能改.我尝试改了下,报错了.因为c语言里面设置了包的使用路径.太多了,我就不想改了,如果有兴趣的小伙伴,可以进去改一下

这里必须要这么做,不然会崩

然后把Android目录下的examples拿出来.这就是集成样例.

zbar/Android/examples

直接运行,这里需要给照相机权限.

完成

扫码的核心方法就是,camera的onPreviewFrame回调.


    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        Camera.Parameters parameters = camera.getParameters();
        Camera.Size       size       = parameters.getPreviewSize();
        Image             barcode    = new Image(size.width, size.height, "Y800");
        barcode.setData(data);
        int  result = scanner.scanImage(barcode);
        if (result != 0) {
            mCameraManager.stop();
            SymbolSet syms = scanner.getResults();
            // 扫码结果页
            for (Symbol sym : syms) {
               System.out.println(sym.getData());
            }
        }
    }

这是我的github地址,jni.zip是我已经编译好的.ndk-build.也可以直接出so文件

https://github.com/ccx1/EZbar

这里的viewfinderview,是我拿我以前的项目,封装zxing的时候写的.

这里zxing我那时候优化了很久,终于达到聚焦扫码快速的时候.

https://github.com/ccx1/EZxing

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现C语言调用zbar实现二维码扫码,需要进行以下步骤: 1. 下载zbar的源码,并进行编译安装。 2. 在C程序中引用zbar的头文件,并链接zbar的库文件。 3. 使用zbar提供的API函数实现二维码扫码功能。 以下是一个简单的示例程序: ``` #include <stdio.h> #include <zbar.h> int main() { // 初始化zbar zbar_image_scanner_t *scanner = zbar_image_scanner_create(); zbar_image_scanner_set_config(scanner, 0, ZBAR_CFG_ENABLE, 1); // 读取二维码图片 zbar_image_t *image = zbar_image_create(); zbar_image_set_format(image, *(int*)"Y800"); // 设置图片格式为Y800 FILE *file = fopen("qrcode.jpg", "rb"); fseek(file, 0, SEEK_END); long size = ftell(file); fseek(file, 0, SEEK_SET); char *data = (char*)malloc(size); fread(data, 1, size, file); zbar_image_set_size(image, 640, 480); // 设置图片大小 zbar_image_set_data(image, data, size, zbar_image_free_data); // 扫描二维码 int n = zbar_scan_image(scanner, image); const zbar_symbol_t *symbol = zbar_image_first_symbol(image); for (; symbol; symbol = zbar_symbol_next(symbol)) { const char *data = zbar_symbol_get_data(symbol); printf("QR Code: %s\n", data); } // 释放资源 zbar_image_destroy(image); zbar_image_scanner_destroy(scanner); fclose(file); return 0; } ``` 在这个示例程序中,我们首先初始化了zbar,然后读取了一个名为qrcode.jpg的二维码图片,并设置了图片的格式和大小。接着,我们调用zbar_scan_image函数扫描二维码,并遍历所有扫描到的二维码进行输出。最后,我们释放了所有的资源。 需要注意的是,这个示例程序仅供参考,实际使用时可能需要进行一些修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值