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  and nl_langinfo(CODESET). */
#define HAVE_LANGINFO_CODESET 1

改完后:

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

第二步打开

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

然后

找到int c; 在get_charset_aliases()方法中.全局搜索也可以Android-从0开始集成编译zbar到能光速扫出二维码_第1张图片

修改成

Android-从0开始集成编译zbar到能光速扫出二维码_第2张图片

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下面

Android-从0开始集成编译zbar到能光速扫出二维码_第3张图片

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

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

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

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

#
# Android NDK makefile 
#
# build - /ndk-build ICONV_SRC= 
# clean -  /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-build ICONV_SRC=
# clean -  /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下面,也就是以下这些,.

Android-从0开始集成编译zbar到能光速扫出二维码_第4张图片

然后需要在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

 

 

 

 

你可能感兴趣的:(Android-从0开始集成编译zbar到能光速扫出二维码)