移动开发 \ Unity 3D \ cocos2dx-lua在ios上实现生成及扫描二维码

cocos2dx-lua在ios上实现生成及扫描二维码

总点击221
简介:首先说明下,我是支持用iOS原生方法实现的。不过扫描二维码原生方法不支持ios7.0之前的设备,所以生成二维码用的原生方法实现,而扫描二维码用zBarsdk实现的(当然也可以用google官方的zXingsdk)。其中zBar中包含生成


首先说明下,我是支持用iOS原生方法实现的。不过扫描二维码原生方法不支持ios7.0之前的设备,所以生成二维码用的原生方法实现,而扫描二维码用zBar sdk实现的(当然也可以用google官方的zXing sdk)。其中zBar中包含生成二维码的方法,而且更多样,我只是喜欢尽量用原生方法来实现。

这里我把所有生成二维码的代码和lua调用的扫描二维码方法都放在了项目->frameworks->runtime-src->proj.ios_mac->ios->AppController.h和AppController.mm中

而zBar sdk及相关类放到了项目->frameworks->runtime-src->proj.ios_mac->ios下。

-----1.原生生成二维码

------------1.1AppController.h中添加代码:

[cpp]view plaincopy

//生成二维码+(CIImage*)creatQRcodeWithUrlstring:(NSString*)urlString;//改变图片大小(正方形图片)+(UIImage*)changeImageSizeWithCIImage:(CIImage*)ciImageandSize:(CGFloat)size;//保存(暂时没用)+(BOOL)writeImage:(UIImage*)imagetoFileAtPath:(NSString*)aPath;//生成二维码+(void)createQRCode:(NSDictionary*)info;------------1.2AppController.mm中添加代码:


[cpp]view plaincopy

/***根据字符串生成二维码CIImage对象**@paramurlString需要生成二维码的字符串**@return生成的二维码*/+(CIImage*)creatQRcodeWithUrlstring:(NSString*)urlString{//1.实例化二维码滤镜CIFilter*filter=[CIFilterfilterWithName:@"CIQRCodeGenerator"];//2.恢复滤镜的默认属性(因为滤镜有可能保存上一次的属性)[filtersetDefaults];//3.将字符串转换成NSdataNSData*data=[urlStringdataUsingEncoding:NSUTF8StringEncoding];//4.通过KVO设置滤镜,传入data,将来滤镜就知道要通过传入的数据生成二维码[filtersetValue:dataforKey:@"inputMessage"];//5.生成二维码CIImage*outputImage=[filteroutputImage];returnoutputImage;}/***改变图片大小(正方形图片)**@paramciImage需要改变大小的CIImage对象的图片*@paramsize图片大小(正方形图片只需要一个数)**@return生成的目标图片*/+(UIImage*)changeImageSizeWithCIImage:(CIImage*)ciImageandSize:(CGFloat)size{CGRectextent=CGRectIntegral(ciImage.extent);CGFloatscale=MIN(size/CGRectGetWidth(extent),size/CGRectGetHeight(extent));//创建bitmap;size_twidth=CGRectGetWidth(extent)*scale;size_theight=CGRectGetHeight(extent)*scale;CGColorSpaceRefcs=CGColorSpaceCreateDeviceGray();CGContextRefbitmapRef=CGBitmapContextCreate(nil,width,height,8,cs,(CGBitmapInfo)kCGImageAlphaNone);CIContext*context=[CIContextcontextWithOptions:nil];CGImageRefbitmapImage=[contextcreateCGImage:ciImagefromRect:extent];CGContextSetInterpolationQuality(bitmapRef,kCGInterpolationNone);CGContextScaleCTM(bitmapRef,scale,scale);CGContextDrawImage(bitmapRef,extent,bitmapImage);//保存bitmap到图片CGImageRefscaledImage=CGBitmapContextCreateImage(bitmapRef);CGContextRelease(bitmapRef);CGImageRelease(bitmapImage);return[UIImageimageWithCGImage:scaledImage];}+(BOOL)writeImage:(UIImage*)imagetoFileAtPath:(NSString*)aPath{if((image==nil)||(aPath==nil)||([aPathisEqualToString:@""]))returnNO;@try{NSData*imageData=nil;NSString*ext=[aPathpathExtension];if([extisEqualToString:@"png"]){imageData=UIImagePNGRepresentation(image);}else{//therest,wewritetojpeg//0.best,1.lost.aboutcompress.imageData=UIImageJPEGRepresentation(image,0);}if((imageData==nil)||([imageDatalength]<=0))returnNO;[imageDatawriteToFile:aPathatomically:YES];returnYES;}@catch(NSException*e){NSLog(@"createthumbnailexception.");}returnNO;}/**项目-TARGETS-fightGame-mobile-BuildPhases-LinkBinaryWithLibraries添加CoreImage.framework*/+(void)createQRCode:(NSDictionary*)info{int_callBack=[[infoobjectForKey:@"listener"]intValue];NSString*qrCodeStr=[infoobjectForKey:@"qrCodeStr"];CIImage*ciImage=[selfcreatQRcodeWithUrlstring:qrCodeStr];UIImage*uiImage=[selfchangeImageSizeWithCIImage:ciImageandSize:180];NSData*imageData=UIImagePNGRepresentation(uiImage);std::stringpath=cocos2d::FileUtils::getInstance()->getWritablePath()+"qrCode.png";constchar*pathC=path.c_str();NSString*pathN=[NSStringstringWithUTF8String:pathC];boolisSuccess=[imageDatawriteToFile:pathNatomically:YES];cocos2d::LuaBridge::pushLuaFunctionById(_callBack);cocos2d::LuaValueDictdict;dict["isSuccess"]=cocos2d::LuaValue::booleanValue(isSuccess);cocos2d::LuaBridge::getStack()->pushLuaValueDict(dict);cocos2d::LuaBridge::getStack()->executeFunction(1);cocos2d::LuaBridge::releaseLuaFunctionById(_callBack);}其中createQRcode方法为最终lua掉用oc的方法,将生成的图片存到cocos2dx的writablePath下,并保存为"qrCode.png"。最后在lua端取出用sprite显示。

------------1.3lua调用createQRcode方法,并显示

[cpp]view plaincopy

localcallBack=function(message)localfilePath=cc.FileUtils:getInstance():getWritablePath()filePath=filePath.."qrCode.png"localrect=cc.rect(0,180,180)localsprite=cc.Sprite:create()sprite:initWithFile(filePath,rect)sprite:setPosition(300,300)self:addChild(sprite)endlocalinfo={listener=callBack,qrCodeStr="https://www.baidu.com/"}luaoc.callStaticMethod("AppController","createQRCode",info)------------1.4添加CoreImage.framework依赖框架(二维码扫描需要用到)

项目->TARGETS->Build Phases->Link Binary With Libraries->左下角“+”号,search框中输入CoreImage.framework,选择匹配的选项即可。


-----2.zBar sdk实现二维码扫描

------------2.1下载zBar sdk


地址在后面给出。

------------2.2将zBarSDK解压并将解压后的zBarSDK导入到工程项目->frameworks->runtime-src->proj.ios_mac->ios下。

解压后的zBarSDK目录包含:Headers,libzbar.a,Resources。

如果导入工程后没有自动添加libzbar.a依赖框架,则需要手动添加该依赖框架(如1.4)。

------------2.3项目->frameworks->runtime-src->proj.ios_mac->ios->zBarSDK下新建ZCZBarViewController.h和ZCZBarViewController.mm两个文件,并导入工程,代码如下。


------------2.4ZCZBarViewController.h代码:


[cpp]view plaincopy

/*版本说明iOS研究院3050449551.8版本剔除生成二维码文件,使用iOS7原生生成二维码1.7版本修复了开启相机点击,用户如果点击拒绝,会导致崩溃的问题1.6版本增加了支持了区别条码和二维码,可以关闭扫描二维码来增加条码扫描速度1.5版本修正了iOS6下扫描会卡死,增加了iOS7下支持条形码,修改了算法,增加了效率1.4版本支持iOS8系统,修改了相应UI的适配问题1.3版本全新支持arm7sarm64全新支持ARC1.2版本ZC封装的ZBar二维码SDK1、更新类名从CustomViewController更改为ZCZBarViewController2、删除掉代理的相关代码1.1版本ZC封装的ZBar二维码SDK~1、增加block回调2、取消代理3、增加适配IOS7(ios7在AVFoundation中增加了扫描二维码功能)1.0版本ZC封装的ZBar二维码SDK~1.0版本初始建立二维码编译顺序Zbar编译需要添加AVFoundationCoreMediaCoreVideoQuartzCorelibiconv//示例代码扫描代码BOOL代表是否关闭二维码扫描,专门扫描条形码ZCZBarViewController*vc=[[ZCZBarViewControlleralloc]initWithIsQRCode:NOBlock:^(NSString*result,BOOLisFinish){if(isFinish){NSLog(@"最后的结果%@",result);}}];[selfpresentViewController:vcanimated:YEScompletion:nil];生成二维码[ZCZBarViewControllercreateImageWithImageView:imageViewString:@"http://www.baidu.com"Scale:4];*/#import<UIKit/UIKit.h>#import<AVFoundation/AVFoundation.h>#import"ZBarReaderController.h"#import<CoreImage/CoreImage.h>#defineIOS7[[[UIDevicecurrentDevice]systemVersion]floatValue]>=7@interfaceZCZBarViewController:UIViewController<AVCaptureVideoDataOutputSampleBufferDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate,ZBarReaderDelegate,AVCaptureMetadataOutputObjectsDelegate>{intnum;BOOLupOrdown;NSTimer*timer;UIImageView*_line;}@property(nonatomic,strong)AVCaptureVideoPreviewLayer*captureVideoPreviewLayer;@property(nonatomic,strong)AVCaptureSession*captureSession;@property(nonatomic,assign)BOOLisScanning;@property(nonatomic,copy)void(^ScanResult)(NSString*result,BOOLisSucceed);@property(nonatomic)BOOLisQRCode;//初始化函数-(id)initWithIsQRCode:(BOOL)isQRCodeBlock:(void(^)(NSString*,BOOL))a;//正则表达式对扫描结果筛选+(NSString*)zhengze:(NSString*)str;//创建二维码+(void)createImageWithImageView:(UIImageView*)imageViewString:(NSString*)strScale:(CGFloat)scale;@end------------2.4ZCZBarViewController.mm代码:


[cpp]view plaincopy

#import"ZCZBarViewController.h"#import<AssetsLibrary/AssetsLibrary.h>@interfaceZCZBarViewController()@end#defineWIDTH(([UIScreenmainScreen].bounds.size.width>[UIScreenmainScreen].bounds.size.height)?[UIScreenmainScreen].bounds.size.width:[UIScreenmainScreen].bounds.size.height)//[UIScreenmainScreen].bounds.size.width#defineHEIGHT(([UIScreenmainScreen].bounds.size.width<[UIScreenmainScreen].bounds.size.height)?[UIScreenmainScreen].bounds.size.width:[UIScreenmainScreen].bounds.size.height)//[UIScreenmainScreen].bounds.size.height@implementationZCZBarViewController-(id)initWithNibName:(NSString*)nibNameOrNilbundle:(NSBundle*)nibBundleOrNil{self=[superinitWithNibName:nibNameOrNilbundle:nibBundleOrNil];if(self){//Custominitialization}returnself;}-(id)initWithIsQRCode:(BOOL)isQRCodeBlock:(void(^)(NSString*,BOOL))a{if(self=[superinit]){self.ScanResult=a;self.isQRCode=isQRCode;}returnself;}-(void)createView{//qrcode_scan_bg_Green_iphone5@2x.pngqrcode_scan_bg_Green@2x.pngUIImage*image=[UIImageimageNamed:@"qrcode_scan_bg_Green@2x.png"];floatcapWidth=image.size.width/2;floatcapHeight=image.size.height/2;image=[imagestretchableImageWithLeftCapWidth:capWidthtopCapHeight:capHeight];UIImageView*bgImageView=[[UIImageViewalloc]initWithFrame:CGRectMake(0,64,WIDTH,HEIGHT-64)];//bgImageView.contentMode=UIViewContentModeTop;bgImageView.clipsToBounds=YES;bgImageView.image=image;bgImageView.userInteractionEnabled=YES;[self.viewaddSubview:bgImageView];//UILabel*label=[[UILabelalloc]initWithFrame:CGRectMake(0,bgImageView.frame.size.height-140,40)];//label.text=@"将取景框对准二维码,即可自动扫描。";//label.textColor=[UIColorwhiteColor];//label.textAlignment=NSTextAlignmentCenter;//label.lineBreakMode=NSLineBreakByWordWrapping;//label.numberOfLines=2;//label.font=[UIFontsystemFontOfSize:12];//label.backgroundColor=[UIColorclearColor];//[bgImageViewaddSubview:label];_line=[[UIImageViewalloc]initWithFrame:CGRectMake((WIDTH-220)/2,70,220,2)];_line.image=[UIImageimageNamed:@"qrcode_scan_light_green.png"];[bgImageViewaddSubview:_line];////下方相册//UIImageView*scanImageView=[[UIImageViewalloc]initWithFrame:CGRectMake(0,HEIGHT-100,100)];//scanImageView.image=[UIImageimageNamed:@"qrcode_scan_bar.png"];//scanImageView.userInteractionEnabled=YES;//[self.viewaddSubview:scanImageView];//NSArray*unSelectImageNames=@[@"qrcode_scan_btn_photo_nor.png",@"qrcode_scan_btn_flash_nor.png",@"qrcode_scan_btn_myqrcode_nor.png"];//NSArray*selectImageNames=@[@"qrcode_scan_btn_photo_down.png",@"qrcode_scan_btn_flash_down.png",@"qrcode_scan_btn_myqrcode_down.png"];////for(inti=0;i<unSelectImageNames.count;i++){//UIButton*button=[UIButtonbuttonWithType:UIButtonTypeCustom];//[buttonsetImage:[UIImageimageNamed:unSelectImageNames[i]]forState:UIControlStateNormal];//[buttonsetImage:[UIImageimageNamed:selectImageNames[i]]forState:UIControlStateHighlighted];//button.frame=CGRectMake(WIDTH/3*i,WIDTH/3,100);//[scanImageViewaddSubview:button];//if(i==0){//[buttonaddTarget:selfaction:@selector(pressPhotoLibraryButton:)forControlEvents:UIControlEventTouchUpInside];//}//if(i==1){//[buttonaddTarget:selfaction:@selector(flashLightClick)forControlEvents:UIControlEventTouchUpInside];//}//if(i==2){//button.hidden=YES;//}////}//假导航//UIImageView*navImageView=[[UIImageViewalloc]initWithFrame:CGRectMake(0,64)];//navImageView.image=[UIImageimageNamed:@"qrcode_scan_bar.png"];//navImageView.userInteractionEnabled=YES;//[self.viewaddSubview:navImageView];UILabel*titleLabel=[[UILabelalloc]initWithFrame:CGRectMake(WIDTH/2-32,20,44)];titleLabel.textColor=[UIColorwhiteColor];titleLabel.backgroundColor=[UIColorclearColor];titleLabel.text=@"扫一扫";[self.viewaddSubview:titleLabel];//[navImageViewaddSubview:titleLabel];UIButton*button=[UIButtonbuttonWithType:UIButtonTypeCustom];[buttonsetImage:[UIImageimageNamed:@"qrcode_scan_titlebar_back_pressed@2x.png"]forState:UIControlStateHighlighted];[buttonsetImage:[UIImageimageNamed:@"qrcode_scan_titlebar_back_nor.png"]forState:UIControlStateNormal];[buttonsetFrame:CGRectMake(10,10,48,48)];[buttonaddTarget:selfaction:@selector(pressCancelButton:)forControlEvents:UIControlEventTouchUpInside];[self.viewaddSubview:button];timer=[NSTimerscheduledTimerWithTimeInterval:2target:selfselector:@selector(animation1)userInfo:nilrepeats:YES];}-(void)animation1{[UIViewanimateWithDuration:2animations:^{_line.frame=CGRectMake((WIDTH-220)/2,70+HEIGHT-310,2);}completion:^(BOOLfinished){[UIViewanimateWithDuration:2animations:^{_line.frame=CGRectMake((WIDTH-220)/2,2);}];}];}//开启关闭闪光灯-(void)flashLightClick{AVCaptureDevice*device=[AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];if(device.torchMode==AVCaptureTorchModeOff){//闪光灯开启[devicelockForConfiguration:nil];[devicesetTorchMode:AVCaptureTorchModeOn];}else{//闪光灯关闭[devicesetTorchMode:AVCaptureTorchModeOff];}}-(void)viewDidLoad{//相机界面的定制在self.view上加载即可BOOLCustom=[UIImagePickerControllerisSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];//判断摄像头是否能用if(Custom){[selfinitCapture];//启动摄像头}else{self.view.backgroundColor=[UIColorwhiteColor];}[superviewDidLoad];[selfcreateView];}#pragmamark选择相册-(void)pressPhotoLibraryButton:(UIButton*)button{if(timer){[timerinvalidate];timer=nil;}_line.frame=CGRectMake((WIDTH-220)/2,2);num=0;upOrdown=NO;UIImagePickerController*picker=[[UIImagePickerControlleralloc]init];picker.allowsEditing=YES;picker.delegate=self;picker.sourceType=UIImagePickerControllerSourceTypePhotoLibrary;[selfpresentViewController:pickeranimated:YEScompletion:^{self.isScanning=NO;[self.captureSessionstopRunning];}];}#pragmamark点击取消-(void)pressCancelButton:(UIButton*)button{self.isScanning=NO;[self.captureSessionstopRunning];self.ScanResult(nil,NO);if(timer){[timerinvalidate];timer=nil;}_line.frame=CGRectMake((WIDTH-220)/2,2);num=0;upOrdown=NO;[selfdismissViewControllerAnimated:YEScompletion:nil];}#pragmamark开启相机-(void)initCapture{//ios6上也没有“设置--隐私--相机”那一项if(IOS7){NSString*mediaType=AVMediaTypeVideo;AVAuthorizationStatusauthStatus=[AVCaptureDeviceauthorizationStatusForMediaType:mediaType];if(authStatus==AVAuthorizationStatusRestricted||authStatus==AVAuthorizationStatusDenied){NSString*str=[NSStringstringWithFormat:@"请在系统设置-%@-相机中打开允许使用相机",[[[NSBundlemainBundle]infoDictionary]objectForKey:(NSString*)kCFBundleNameKey]];UIAlertView*alert=[[UIAlertViewalloc]initWithTitle:@"提示"message:strdelegate:nilcancelButtonTitle:@"确定"otherButtonTitles:nil,nil];[alertshow];return;}}self.captureSession=[[AVCaptureSessionalloc]init];AVCaptureDevice*inputDevice=[AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];AVCaptureDeviceInput*captureInput=[AVCaptureDeviceInputdeviceInputWithDevice:inputDeviceerror:nil];[self.captureSessionaddInput:captureInput];AVCaptureVideoDataOutput*captureOutput=[[AVCaptureVideoDataOutputalloc]init];captureOutput.alwaysDiscardsLateVideoFrames=YES;if(IOS7){AVCaptureMetadataOutput*_output=[[AVCaptureMetadataOutputalloc]init];[_outputsetMetadataObjectsDelegate:selfqueue:dispatch_get_main_queue()];[self.captureSessionsetSessionPreset:AVCaptureSessionPresetHigh];[self.captureSessionaddOutput:_output];//在这里修改了,可以让原生兼容二维码和条形码,无需在使用Zbarif(_isQRCode){_output.metadataObjectTypes=@[AVMetadataObjectTypeQRCode];}else{_output.metadataObjectTypes=@[AVMetadataObjectTypeEAN13Code,AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeCode128Code,AVMetadataObjectTypeQRCode];}if(!self.captureVideoPreviewLayer){self.captureVideoPreviewLayer=[AVCaptureVideoPreviewLayerlayerWithSession:self.captureSession];}//NSLog(@"prev%p%@",self.prevLayer,self.prevLayer);self.captureVideoPreviewLayer.frame=CGRectMake(0,HEIGHT);//self.view.bounds;self.captureVideoPreviewLayer.videoGravity=AVLayerVideoGravityResizeAspectFill;[self.view.layeraddSublayer:self.captureVideoPreviewLayer];self.isScanning=YES;[self.captureSessionstartRunning];}else{dispatch_queue_tqueue=dispatch_queue_create("myQueue",NULL);[captureOutputsetSampleBufferDelegate:selfqueue:queue];NSString*key=(NSString*)kCVPixelBufferPixelFormatTypeKey;NSNumber*value=[NSNumbernumberWithUnsignedInt:kCVPixelFormatType_32BGRA];NSDictionary*videoSettings=[NSDictionarydictionaryWithObject:valueforKey:key];[captureOutputsetVideoSettings:videoSettings];[self.captureSessionaddOutput:captureOutput];NSString*preset=0;if(NSClassFromString(@"NSOrderedSet")&&//Proxyfor"isthisiOS5"...[UIScreenmainScreen].scale>1&&[inputDevicesupportsAVCaptureSessionPreset:AVCaptureSessionPresetiFrame960x540]){//NSLog(@"960");preset=AVCaptureSessionPresetiFrame960x540;}if(!preset){//NSLog(@"MED");preset=AVCaptureSessionPresetMedium;}self.captureSession.sessi;if(!self.captureVideoPreviewLayer){self.captureVideoPreviewLayer=[AVCaptureVideoPreviewLayerlayerWithSession:self.captureSession];}//NSLog(@"prev%p%@",HEIGHT);//self.view.bounds;self.captureVideoPreviewLayer.videoGravity=AVLayerVideoGravityResizeAspectFill;[self.view.layeraddSublayer:self.captureVideoPreviewLayer];self.isScanning=YES;[self.captureSessionstartRunning];}}-(UIImage*)imageFromSampleBuffer:(CMSampleBufferRef)sampleBuffer{CVImageBufferRefimageBuffer=CMSampleBufferGetImageBuffer(sampleBuffer);//LockthebaseaddressofthepixelbufferCVPixelBufferLockBaseAddress(imageBuffer,0);//Getthenumberofbytesperrowforthepixelbuffersize_tbytesPerRow=CVPixelBufferGetBytesPerRow(imageBuffer);//Getthepixelbufferwidthandheightsize_twidth=CVPixelBufferGetWidth(imageBuffer);size_theight=CVPixelBufferGetHeight(imageBuffer);//Createadevice-dependentRGBcolorspaceCGColorSpaceRefcolorSpace=CGColorSpaceCreateDeviceRGB();if(!colorSpace){NSLog(@"CGColorSpaceCreateDeviceRGBfailure");returnnil;}//Getthebaseaddressofthepixelbuffervoid*baseAddress=CVPixelBufferGetBaseAddress(imageBuffer);//Getthedatasizeforcontiguousplanesofthepixelbuffer.size_tbufferSize=CVPixelBufferGetDataSize(imageBuffer);//CreateaQuartzdirect-accessdataproviderthatusesdatawesupplyCGDataProviderRefprovider=CGDataProviderCreateWithData(NULL,baseAddress,bufferSize,NULL);//CreateabitmapimagefromdatasuppliedbyourdataproviderCGImageRefcgImage=CGImageCreate(width,32,bytesPerRow,colorSpace,kCGImageAlphaNoneSkipFirst|kCGBitmapByteOrder32Little,provider,NULL,true,kCGRenderingIntentDefault);CGDataProviderRelease(provider);CGColorSpaceRelease(colorSpace);//CreateandreturnanimageobjectrepresentingthespecifiedQuartzimageUIImage*image=[UIImageimageWithCGImage:cgImage];returnimage;}#pragmamark对图像进行解码-(void)decodeImage:(UIImage*)image{self.isScanning=NO;ZBarSymbol*symbol=nil;ZBarReaderController*read=[ZBarReaderControllernew];read.readerDelegate=self;CGImageRefcgImageRef=image.CGImage;for(symbolin[readscanImage:cgImageRef])break;if(symbol!=nil){if(timer){[timerinvalidate];timer=nil;}_line.frame=CGRectMake((WIDTH-220)/2,2);num=0;upOrdown=NO;self.ScanResult(symbol.data,YES);[self.captureSessionstopRunning];[selfdismissViewControllerAnimated:YEScompletion:nil];}else{timer=[NSTimerscheduledTimerWithTimeInterval:.02target:selfselector:@selector(animation1)userInfo:nilrepeats:YES];num=0;upOrdown=NO;self.isScanning=YES;[self.captureSessionstartRunning];}}#pragmamark-AVCaptureVideoDataOutputSampleBufferDelegate-(void)captureOutput:(AVCaptureOutput*)captureOutputdidOutputSampleBuffer:(CMSampleBufferRef)sampleBufferfromConnection:(AVCaptureConnection*)connection{UIImage*image=[selfimageFromSampleBuffer:sampleBuffer];[selfdecodeImage:image];}#pragmamarkAVCaptureMetadataOutputObjectsDelegate//IOS7下触发-(void)captureOutput:(AVCaptureOutput*)captureOutputdidOutputMetadataObjects:(NSArray*)metadataObjectsfromConnection:(AVCaptureConnection*)connection{if(metadataObjects.count>0){AVMetadataMachineReadableCodeObject*metadataObject=[metadataObjectsobjectAtIndex:0];self.ScanResult(metadataObject.stringValue,YES);}[self.captureSessionstopRunning];_line.frame=CGRectMake((WIDTH-220)/2,2);num=0;upOrdown=NO;[selfdismissViewControllerAnimated:YEScompletion:nil];}#pragmamark-UIImagePickerControllerDelegate-(void)imagePickerController:(UIImagePickerController*)pickerdidFinishPickingMediaWithInfo:(NSDictionary*)info{if(timer){[timerinvalidate];timer=nil;}_line.frame=CGRectMake((WIDTH-220)/2,2);num=0;upOrdown=NO;UIImage*image=[infoobjectForKey:@"UIImagePickerControllerEditedImage"];[selfdismissViewControllerAnimated:YEScompletion:^{[selfdecodeImage:image];}];}-(void)imagePickerControllerDidCancel:(UIImagePickerController*)picker{if(timer){[timerinvalidate];timer=nil;}_line.frame=CGRectMake((WIDTH-220)/2,2);num=0;upOrdown=NO;timer=[NSTimerscheduledTimerWithTimeInterval:2target:selfselector:@selector(animation1)userInfo:nilrepeats:YES];[selfdismissViewControllerAnimated:YEScompletion:^{self.isScanning=YES;[self.captureSessionstartRunning];}];}#pragmamark-DecoderDelegate+(NSString*)zhengze:(NSString*)str{NSError*error;//http+:[^s]*这是检测网址的正则表达式NSRegularExpression*regex=[NSRegularExpressionregularExpressionWithPattern:@"http+:[^s]*"options:0error:&error];//筛选if(regex!=nil){NSTextCheckingResult*firstMatch=[regexfirstMatchInString:stroptions:0range:NSMakeRange(0,[strlength])];if(firstMatch){NSRangeresultRange=[firstMatchrangeAtIndex:0];//从urlString中截取数据NSString*result1=[strsubstringWithRange:resultRange];NSLog(@"正则表达后的结果%@",result1);returnresult1;}}returnnil;}+(void)createImageWithImageView:(UIImageView*)imageViewString:(NSString*)strScale:(CGFloat)scale{CIFilter*filter=[CIFilterfilterWithName:@"CIQRCodeGenerator"];[filtersetDefaults];NSData*data=[strdataUsingEncoding:NSUTF8StringEncoding];[filtersetValue:dataforKey:@"inputMessage"];CIImage*outputImage=[filteroutputImage];CIContext*context=[CIContextcontextWithOptions:nil];CGImageRefcgImage=[contextcreateCGImage:outputImagefromRect:[outputImageextent]];UIImage*image=[UIImageimageWithCGImage:cgImagescale:1.0orientation:UIImageOrientationUp];UIImage*resized=nil;CGFloatwidth=image.size.width*scale;CGFloatheight=image.size.height*scale;UIGraphicsBeginImageContext(CGSizeMake(width,height));CGContextRefcontext1=UIGraphicsGetCurrentContext();CGContextSetInterpolationQuality(context1,kCGInterpolationNone);[imagedrawInRect:CGRectMake(0,-50,height)];resized=UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();imageView.image=resized;CGImageRelease(cgImage);}-(void)didReceiveMemoryWarning{[superdidReceiveMemoryWarning];//Disposeofanyresourcesthatcanberecreated.}/*#pragmamark-Navigation//Inastoryboard-basedapplication,youwilloftenwanttodoalittlepreparationbeforenavigation-(void)prepareForSegue:(UIStoryboardSegue*)seguesender:(id)sender{//Getthenewviewcontrollerusing[seguedestinationViewController].//Passtheselectedobjecttothenewviewcontroller.}*/////支持旋转//-(BOOL)shouldAutorotate{//returnNO;//}////支持的方向//-(UIInterfaceOrientationMask)supportedInterfaceOrientations{//returnUIInterfaceOrientationMaskPortrait;//}@end------------2.5AppController.h中添加代码:

[cpp]view plaincopy

//获取当前正在显示的ViewController+(UIViewController*)getCurrentVC;//获取当前屏幕中present出来的viewcontroller。-(UIViewController*)getPresentedViewController;//扫描二维码+(void)scanQRCode:(NSDictionary*)info;------------2.5AppController.mm中添加代码:


[cpp]view plaincopy

//获取当前正在显示的ViewController+(UIViewController*)getCurrentVC{UIViewController*result=nil;UIWindow*window=[[UIApplicationsharedApplication]keyWindow];if(window.windowLevel!=UIWindowLevelNormal){NSArray*windows=[[UIApplicationsharedApplication]windows];for(UIWindow*tmpWininwindows){if(tmpWin.windowLevel==UIWindowLevelNormal){window=tmpWin;break;}}}UIView*frontView=[[windowsubviews]objectAtIndex:0];idnextResponder=[frontViewnextResponder];if([nextResponderisKindOfClass:[UIViewControllerclass]])result=nextResponder;elseresult=window.rootViewController;returnresult;}//获取当前屏幕中present出来的viewcontroller。-(UIViewController*)getPresentedViewController{UIViewController*appRootVC=[UIApplicationsharedApplication].keyWindow.rootViewController;UIViewController*topVC=appRootVC;if(topVC.presentedViewController){topVC=topVC.presentedViewController;}returntopVC;}+(void)scanQRCode:(NSDictionary*)info{int_callBack=[[infoobjectForKey:@"listener"]intValue];//SGScanningQRCodeVC*scanningQRCodeVC=[[SGScanningQRCodeVCalloc]init];//[scanningQRCodeVCsetupScanningQRCode];UIViewController*nowViewController=[selfgetCurrentVC];ZCZBarViewController*vc=[[ZCZBarViewControlleralloc]initWithIsQRCode:NOBlock:^(NSString*result,result);UIViewController*nowViewController=[selfgetCurrentVC];dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(0.02*NSEC_PER_SEC)),dispatch_get_main_queue(),^{[nowViewControllerdismissViewControllerAnimated:NOcompletion:nil];cocos2d::LuaBridge::pushLuaFunctionById(_callBack);cocos2d::LuaValueDictdict;dict["scanResult"]=cocos2d::LuaValue::stringValue([resultUTF8String]);cocos2d::LuaBridge::getStack()->pushLuaValueDict(dict);cocos2d::LuaBridge::getStack()->executeFunction(1);cocos2d::LuaBridge::releaseLuaFunctionById(_callBack);});}}];[nowViewControllerpresentViewController:vcanimated:YEScompletion:nil];}其中scanQRCode方法为最终lua掉用oc的方法,在扫描识别出二维码信息之后会将信息传回给lua端。

------------2.6lua掉用oc扫描二维码代码:


[cpp]view plaincopy

localcallBack=function(message)print("messagescanResult:",message.scanResult)Utils.showTip(message.scanResult)endlocalinfo={listener=callBack}luaoc.callStaticMethod("AppController","scanQRCode",info)------------2.7添加依赖框架


如上1.4,扫描二维码需要添加框架AVFoundation,CoreMedie,CoreVideo,QuartzCore,libiconv

-----3.扫描界面横竖屏说明

如果游戏界面是横屏的,而二维码扫描界面要求是竖屏的,则需要做些操作。

------------3.1增加竖屏支持

项目->TARGETS->General->Deployment Info->Device Orientation->勾选Portrait,Landscape Left,Landscape Right。

------------3.2让游戏界面只支持横屏


项目->frameworks->runtime-src->proj.ios_mac->ios->RootViewController.mm中supportedInterfaceOrientations方法修改为:


[cpp]view plaincopy

//Forios6,usesupportedInterfaceOrientations&shouldAutorotateinstead-(NSUInteger)supportedInterfaceOrientations{returnUIInterfaceOrientationMaskLandscapeLeft|UIInterfaceOrientationMaskLandscapeRight;//#ifdef__IPHONE_6_0//returnUIInterfaceOrientationMaskAllButUpsideDown;//#endif}------------3.3扫描二维码界面只支持竖屏

项目->frameworks->runtime-src->proj.ios_mac->ios->ZCZBarViewController.mm中增加代码:


[cpp]view plaincopy

////支持旋转//-(BOOL)shouldAutorotate{//returnNO;//}////支持的方向//-(UIInterfaceOrientationMask)supportedInterfaceOrientations{//returnUIInterfaceOrientationMaskPortrait;//}------------3.4修改view界面width和height重新适配


项目->frameworks->runtime-src->proj.ios_mac->ios->ZCZBarViewController.mm中将

#define WIDTH和#define HEIGHT两个宏的值颠倒下。

-----4.关于项目->frameworks->runtime-src->proj.ios_mac->ios->ZCZBarViewController.mm中#define WIDTH和#define HEIGHT两个宏


本来因该是

#define WIDTH[UIScreen mainScreen].bounds.size.width

#define HEIGHT[UIScreen mainScreen].bounds.size.height

但在iphone4s(ios6.1.3)上取出的width和height为320,480,而在iPhone6 Plus(ios10.2)上width和height为568,320。

一个宽小于高,一个宽大于高,使得4s横屏的时候,6Plus竖屏是对的,而在6Plus上横屏就是乱的。

所以后来将两个宏修改为(注意:两边一定要带括号,防止编译时宏展开后由于操作符优先级导致的运算错误)

#define WIDTH( ([UIScreen mainScreen].bounds.size.width>[UIScreen mainScreen].bounds.size.height)?[UIScreen mainScreen].bounds.size.width:[UIScreen mainScreen].bounds.size.height )


#defineHEIGHT( ([UIScreen mainScreen].bounds.size.width<[UIScreen mainScreen].bounds.size.height)?[UIScreen mainScreen].bounds.size.width:[UIScreen mainScreen].bounds.size.height )

从而将宽固定取获得的二者较大值,高为二者较小值。若是竖屏,则反过来。

-----5.遇到的一些问题

------------5.1对于ZCZBarViewController.mm中的initCpture方法中有句

AVAuthorizationStatusauthStatus = [AVCaptureDeviceauthorizationStatusForMediaType:mediaType];

注意:此方法只对ios7以上的系统有用,如果是在ios6的系统的话就直接崩溃了,况且ios6上也没有“设置--隐私--相机”那一项。

所以加了if(IOS7)的判断。

------------5.2若碰到错误Cannot synthesize weak property in file using manual reference counting


项目->TARGETS->Build Settings->Apple LLVM 8.0-Language-Objective C->Weak References in Manual Retian Release改为YES


------------5.3编译报错XXXX.o

若编译运行报错,XXXX.o什么什么的问题,则可能是有依赖框架没有导入。

-----6.参考链接


//原生生成二维码

http://blog.csdn.net/zhuming3834/article/details/50832953

//原生二维码扫描


http://www.cocoachina.com/ios/20161009/17696.html


//zBar下载地址


http://download.csdn.net/download/kid_devil/7552613

//zBarDemo下载地址

http://download.csdn.net/detail/shan1991fei/9474417

//二维码扫描之zXing与zBar的优劣

http://blog.csdn.net/l_215851356/article/details/51898514

意见反馈 常见问题 官方微信 返回顶部