柚子快报邀请码778899分享:ZBar开发详解

http://yzkb.51969.com/

博客转载自:https://blog.csdn.net/skillcollege/article/details/38855023

什么是ZBar?

ZBar是一个开源库,用于扫描、读取二维码和条形码。支持的二维码包括:EAN/UPC,QR等。

如果你是一个iPhone应用开发人员,做到二维码模块的时候,是不是会考虑ZBar开源项目来助你一臂之力呢?可是我这里说的是Android平台的开发,我为什么提到ZBar项目呢,难道我要用ZBar在Android平台扫描二维码吗?对的,没有错!这将会是一个极其不错的选择。为什么这么说呢,不是很多Android开发都是用Z*来解析二维码的么?好吧,Z*是我下一篇文章要写的,这里先抛砖引玉说一点点。我将Z*和ZBar做一个比较,说说它们的优缺点,便于大家的取舍。

Z*项目的示例程序对于摄像头的控制写的非常全面,ZBar的没有

ZBar基于C语言编写,解码效率高于Z*项目

ZBar是日本人写的,对于中文解析会乱码这个肯定有人遇到过的,Z*不会乱码

扫描框的绘制,Z*的扫描框绘制是自定义View的,截取区域不好控制,ZBar的可以自定义,只要你会计算截取区

下载ZBar项目

ZBar官网: 传送门

ZBar GitHub地址: 传送门

编写ZBar示例程序

1. 着重介绍一下扫描截取界面的计算

pt: 预览图中二维码图片的左上顶点坐标,也就是手机中相机预览中看到的待扫描二维码的位置

qrheight: 预览图中二维码图片的高度

qrwidth: 预览图中二维码图片的宽度

pheight:预览图的高度,也即camera的分辨率高度

pwidth: 预览图的宽度,也即camera的分辨率宽度

st: 布局文件中扫描框的左上顶点坐标

sheight: 布局文件中扫描框的高度

swidth: 布局文件中扫描框的宽度

cheight:布局文件中相机预览控件的高度

cwidth: 布局文件中相机预览控件的宽度

其中存在这样一个等比例公式

ptx / pwidth = stx / cwidth

pty / pheight = sty / cheight

qrwidth / pwidth = swidth / cwidth

qrheight / pheight = sheight / cheight

并外一种表达形式

ptx = stx * pwidth / cwidth ;

pty = sty * pheight / cheight ;

qrwidth = swidth * pwidth / cwidth ;

qrheight = sheight * pheight / cheight ;

以上ptx,pty,qrwidth,qrheight四个参数也就是ZBar中解码是需要crop时传入的四个参数,如此便知道了截取区域应该如何计算了。这样扫描的灵活性都大大增强了

2. ZBar中文乱码的解决

ZBar扫描含有中文的二维码图片时,结果是乱码的,所以需要修改c文件重新编译打包so文件才行

a. 需要修改的文件是zbar/qrcode/qrdextxt.c文件

/*This is the encoding the standard says is the default.*/

latin1_cd=iconv_open("UTF-8","ISO8859-1");

修改为

/*This is the encoding the standard says is the default.*/

latin1_cd=iconv_open("UTF-8","GBK");

b. 重新编译zbar生成so文件

这个真的需要一定的NDK开发经验了,我个人只是了解一点点NDK的知识,所以在网上找到了一个大神的博客一步一步做下来才算是编译完成了。

最后的编译项目架构

最终生成的so文件

本地方法调用

package com.dtr.zbar.build;

public class ZBarDecoder {

static {

System.loadLibrary("ZBarDecoder");

}

/**

* 解码方法

*

* @param data

* 图片数据

* @param width

* 原始宽度

* @param height

* 原始高度

* @return

*/

public native String decodeRaw(byte[] data, int width, int height);

/**

* 解码方法(需要裁剪图片)

*

* @param data

* 图片数据

* @param width

* 原始宽度

* @param height

* 原始高度

* @param x

* 截取的x坐标

* @param y

* 截取的y坐标

* @param cwidth

* 截取的区域宽度

* @param cheight

* 截取的区域高度

* @return

*/

public native String decodeCrop(byte[] data, int width, int height, int x, int y, int cwidth, int cheight);

}

我的ZBar编译源程序代码: 源码下载

3. 编写Android示例程序

其中CameraConfigurationManager和CameraManager两个类是从ZXing项目中拷贝过来的,方便管理照相机,下一篇的ZXing项目中会更全面的使用ZXing中关于camera的管理类,本篇只是抛砖迎玉。

b.布局界面代码

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

android:id="@+id/capture_container"

android:layout_width="match_parent"

android:layout_height="match_parent" >

android:id="@+id/capture_preview"

android:layout_width="match_parent"

android:layout_height="match_parent" />

android:id="@+id/capture_mask_top"

android:layout_width="match_parent"

android:layout_height="120dp"

android:layout_alignParentTop="true"

android:background="@drawable/shadow" />

android:id="@+id/capture_crop_view"

android:layout_width="200dp"

android:layout_height="200dp"

android:layout_centerHorizontal="true"

android:layout_below="@id/capture_mask_top"

android:background="@drawable/qr_code_bg" >

android:id="@+id/capture_scan_line"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_alignParentTop="true"

android:layout_marginBottom="5dp"

android:layout_marginTop="5dp"

android:src="@drawable/scan_line" />

android:id="@+id/capture_mask_bottom"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_alignParentBottom="true"

android:layout_below="@id/capture_crop_view"

android:background="@drawable/shadow" />

android:id="@+id/capture_mask_left"

android:layout_width="wrap_content"

android:layout_height="match_parent"

android:layout_above="@id/capture_mask_bottom"

android:layout_alignParentLeft="true"

android:layout_below="@id/capture_mask_top"

android:layout_toLeftOf="@id/capture_crop_view"

android:background="@drawable/shadow" />

android:id="@+id/capture_mask_right"

android:layout_width="wrap_content"

android:layout_height="match_parent"

android:layout_above="@id/capture_mask_bottom"

android:layout_alignParentRight="true"

android:layout_below="@id/capture_mask_top"

android:layout_toRightOf="@id/capture_crop_view"

android:background="@drawable/shadow" />