二维码扫描功能随处可见,基本库网上也有很多资源,但最好用的就是ZBar的库。ZBarSDK-for-iOS适配armv7, amrv7s, arm64的github地址,在XCode上引入安装参考:stackoverflow回答。本文讲述怎样引入ZBarSDK-for-iOS,并且作为Unity3D引擎的Plugins的形式,实现IOS设备二维码的扫描功能。
使用download下载zip或是git clone都可以将上述github上获得SDK源码及库。目录结构如下:
将libzbar.a
放到在上图的ZBarSDK目录中,并且将ZBarSDK放到Unity3D的Assets/Scripts/Plugins
中,如图所示:
Plugins中SDK源码及文件最终导出三个接口,以供Unity引擎层C#调用,他们是:
#ifdef __cplusplus
extern "C" {
#endif
void launchScannerImpl(struct ConfigStruct *confStruct);
bool getScannedImageImpl(unsigned char** imageData, int* imageDataLength);
void decodeImageImpl(int symbols, const char* pixelBytes, int64_t length);
#ifdef __cplusplus
}
#endif
这三个接口会在C#层调用,这些接口的声明及实现在EZCodeScannerViewController.h
和EZCodeScannerViewController.mm
中(github地址)
创建一个单例的组件EasyCodeScanner
(github地址),在游戏运行时自动创建GameObject
,并将该组件加入。EasyCodeScanner
组件主要的作用是:
1). 调用且封装由Plugins暴露的三个接口:
#if UNITY_IPHONE
public struct ConfigStruct
{
public bool showUI;
public string defaultText;
public int symbols;
public bool forceLandscape;
}
[DllImport ("__Internal")] private static extern void launchScannerImpl(ref ConfigStruct conf);
[DllImport ("__Internal")] private static extern bool getScannedImageImpl(ref IntPtr pixelBytes, ref int imageDataLength);
[DllImport ("__Internal")] private static extern void decodeImageImpl(int symbols, byte[] pixelBytes, long length);
#endif
封装成launchScanner
函数,供Unity的脚本调用:
public static void launchScanner(bool showUI, string defaultTxt, int symbol, bool forceLandscape) {
if (instance==null) {
Debug.LogError("EasyCodeScanner - launchScanner error : scanner must be initialized before.");
return;
}
#if UNITY_IPHONE
//IPHONE - Display the UIViewController
ConfigStruct conf = new ConfigStruct();
conf.showUI = showUI;
conf.defaultText = defaultTxt;
conf.symbols = symbol;
conf.forceLandscape = forceLandscape;
launchScannerImpl(ref conf);
#endif
}
2). 声明三个委托事件,以便第5步按钮组件触发后,摄像头开启/关闭,二维码解析等事件的触发回调:
//Action delegate
//Callback when returns from the scanner
public static event Action<string> OnScannerMessage;
//Callback which notifies an event
//param : "EVENT_OPENED", "EVENT_CLOSED"
public static event Action<string> OnScannerEvent;
//Callback when decodeImage has decoded the image/texture
public static event Action<string> OnDecoderMessage;
使用Unity5.x自带的UGUI组件,创建一个触发扫描二维码的按钮,如图:
创建QRCodeManager.cs组件(github地址),拖入第5步创建的按钮,实现Scan函数用于按钮的Click相应:
public void Scan()
{
EasyCodeScanner.launchScanner( true, "FEClub", -1, true);
}
然后,在Start()中添加扫描Action的委托事件:
void Start () {
dataStr = "";
// Initialize EasyCodeScanner
EasyCodeScanner.Initialize();
//Register on Actions
EasyCodeScanner.OnScannerMessage += onScannerMessage;
EasyCodeScanner.OnScannerEvent += onScannerEvent;
EasyCodeScanner.OnDecoderMessage += onDecoderMessage;
//Screen.orientation = ScreenOrientation.LandscapeLeft;
}
接着,设置按钮Click响应,如果所示:
最后,将二维码图片返回的data,渲染到按钮的Text上:
//在QRCodeManager.cs的私有变量中,声明
Text t = GetComponentInChildren<Text> ();
然后在onScannerMessage
中渲染:
void onScannerMessage(string data){
Debug.Log("EasyCodeScannerExample - onScannerMessage data=:"+data);
// render the data from QR image
t.text = data;
}
Done!
这个demo的gitbub地址:
https://github.com/csdz/ZBarDemo