二维码扫描利用ZBar实现
上次是根據系統的屬性自己封裝的一個二維碼掃描,這次給大家介紹一下基于ZBar集成的類似于QQ二維碼掃描界面的二維碼掃描的效果。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?最下方配有效果圖哦!
首先,需要引入ZBar第三方庫文件:
ZBarSDK
libqrencode
其次,利用ZBar集成二維碼掃描需要引入的類庫有:
libiconv.tbd
QuartzCore.framework
CoreVideo.framework
CoreMedia.framework
AVFoundation.framework
代碼實現:
-(void)createView{
? ? //掃描頁的背景圖片
? ? UIImageView*bgImageView;
? ? if (self.view.frame.size.height<500) {
? ? ? ? UIImage*image= [UIImage imageNamed:@"qrcode_scan_bg_Green.png"];
? ? ? ? bgImageView=[[UIImageView alloc]initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height-64-100)];
? ? ? ? bgImageView.contentMode=UIViewContentModeTop;
? ? ? ? bgImageView.clipsToBounds=YES;
?? ? ? ?
? ? ? ? bgImageView.image=image;
? ? ? ? bgImageView.userInteractionEnabled=YES;
? ? }else if(self.view.frame.size.height<600){
? ? ? ? UIImage*image= [UIImage imageNamed:@"qrcode_scan_bg_Green_iphone5"];
? ? ? ? bgImageView=[[UIImageView alloc]initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height-64-100)];
? ? ? ? bgImageView.contentMode=UIViewContentModeTop;
? ? ? ? bgImageView.clipsToBounds=YES;
?? ? ? ?
? ? ? ? bgImageView.image=image;
? ? ? ? bgImageView.userInteractionEnabled=YES;
? ? }
? ? else if(self.view.frame.size.height<680){
? ? ? ? UIImage*image= [UIImage imageNamed:@"qrcode_scan_bg_Green_iphone6"];
? ? ? ? bgImageView=[[UIImageView alloc]initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height-64-100)];
? ? ? ? bgImageView.contentMode=UIViewContentModeTop;
? ? ? ? bgImageView.clipsToBounds=YES;
?? ? ? ?
? ? ? ? bgImageView.image=image;
? ? ? ? bgImageView.userInteractionEnabled=YES;
? ? }
? ? else{
? ? ? ? UIImage*image= [UIImage imageNamed:@"qrcode_scan_bg_Green_iphone6p"];
? ? ? ? bgImageView=[[UIImageView alloc]initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height-64-100)];
? ? ? ? bgImageView.contentMode=UIViewContentModeTop;
? ? ? ? bgImageView.clipsToBounds=YES;
?? ? ? ?
? ? ? ? bgImageView.image=image;
? ? ? ? bgImageView.userInteractionEnabled=YES;
? ? }
? ? [self.view addSubview:bgImageView];
?? ?
? ? //掃描框下面的提示語
? ? if (self.view.frame.size.height<600) {
? ? ? ? UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height-200, self.view.frame.size.width, 40)];
? ? ? ? label.text = @"將取景框對準二維碼,即可自動掃描。";
? ? ? ? label.font=[UIFont systemFontOfSize:12];
? ? ? ? label.textColor = [UIColor whiteColor];
? ? ? ? label.textAlignment = NSTextAlignmentCenter;
? ? ? ? label.lineBreakMode = NSLineBreakByWordWrapping;
? ? ? ? label.numberOfLines = 2;
? ? ? ? label.backgroundColor = [UIColor clearColor];
? ? ? ? [bgImageView addSubview:label];
?
? ? }else{
? ? ? ? UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height-300, self.view.frame.size.width, 40)];
? ? ? ? label.text = @"將取景框對準二維碼,即可自動掃描。";
? ? ? ? label.font=[UIFont systemFontOfSize:17];
? ? ? ? label.textColor = [UIColor whiteColor];
? ? ? ? label.textAlignment = NSTextAlignmentCenter;
? ? ? ? label.lineBreakMode = NSLineBreakByWordWrapping;
? ? ? ? label.numberOfLines = 2;
? ? ? ? label.backgroundColor = [UIColor clearColor];
? ? ? ? [bgImageView addSubview:label];
?
? ? }
? ? //初始化掃描線
? ? //4s/5/5s
? ? if (self.view.frame.size.height<600) {
? ? ? ? _line = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.frame.size.width/5.8, 50, 220, 2)];
? ? }
? ? else{
? ? ? ? //6/6s/6p
? ? ? ? _line = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.frame.size.width/4.6, 50, 220, 2)];
? ? }
?? ?
? ? _line.image = [UIImage imageNamed:@"qrcode_scan_light_green.png"];
? ? [bgImageView addSubview:_line];
? ? //下方相冊
? ? UIImageView*scanImageView=[[UIImageView alloc]initWithFrame:CGRectMake(0, bgImageView.frame.size.height+64, self.view.frame.size.width, 100)];
? ? scanImageView.image=[UIImage imageNamed:@"qrcode_scan_bar.png"];
? ? scanImageView.userInteractionEnabled=YES;
? ? [self.view addSubview: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 (int i=0; i<unSelectImageNames.count; i++) {
? ? ? ? UIButton*button=[UIButton buttonWithType:UIButtonTypeCustom];
? ? ? ? [button setImage:[UIImage imageNamed:unSelectImageNames[i]] forState:UIControlStateNormal];
? ? ? ? [button setImage:[UIImage imageNamed:selectImageNames[i]] forState:UIControlStateHighlighted];
? ? ? ? button.frame=CGRectMake(self.view.frame.size.width/3*i, 0, self.view.frame.size.width/3, 100);
? ? ? ? [scanImageView addSubview:button];
? ? ? ? if (i==0) {
? ? ? ? ? ? [button addTarget:self action:@selector(pressPhotoLibraryButton:) forControlEvents:UIControlEventTouchUpInside];
? ? ? ? }
? ? ? ? if (i==1) {
? ? ? ? ? ? [button addTarget:self action:@selector(flashLightClick) forControlEvents:UIControlEventTouchUpInside];
? ? ? ? }
? ? ? ? if (i==2) {
? ? ? ? ? ? button.hidden=YES;
? ? ? ? }??
? ? }
? ? //假導航
? ? UIImageView*navImageView=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 64)];
? ? navImageView.image=[UIImage imageNamed:@"qrcode_scan_bar.png"];
? ? navImageView.userInteractionEnabled=YES;
? ? [self.view addSubview:navImageView];
? ? UILabel*titleLabel=[[UILabel alloc]initWithFrame:CGRectMake(self.view.frame.size.width/2-32,20 , 64, 44)];
? ? titleLabel.textColor=[UIColor whiteColor];
? ? titleLabel.text=@"掃一掃";
? ? [navImageView addSubview:titleLabel];
? ? //返回按鈕
? ? UIButton*button = [UIButton buttonWithType:UIButtonTypeCustom];
? ? [button setImage:[UIImage imageNamed:@"qrcode_scan_titlebar_back_pressed@2x.png"] forState:UIControlStateHighlighted];
? ? [button setImage:[UIImage imageNamed:@"qrcode_scan_titlebar_back_nor.png"] forState:UIControlStateNormal];
?? ?
? ? [button setFrame:CGRectMake(10,15, 48, 48)];
? ? [button addTarget:self action:@selector(pressCancelButton:) forControlEvents:UIControlEventTouchUpInside];
? ? [self.view addSubview:button];
?? ?
? ? timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(animation1) userInfo:nil repeats:YES];
}
?
//掃描線的動畫效果
-(void)animation1
{
? ??? ? [UIView animateWithDuration:2 animations:^{
? ? ? ? if (self.view.frame.size.height<600) {
? ? ? ? ? ? _line.frame = CGRectMake(self.view.frame.size.width/5.8, self.view.frame.size.height/43*22, 220, 2);
? ? ? ? }else{
? ? ? ? ? ? _line.frame = CGRectMake(self.view.frame.size.width/4.6, self.view.frame.size.height/43*22, 220, 2);
? ? ? ? }
? ? }completion:^(BOOL finished) {
? ? ? ? [UIView animateWithDuration:2 animations:^{
? ? ? ? ? ? if (self.view.frame.size.height<600) {
? ? ? ? ? ? ? ? _line.frame = CGRectMake(self.view.frame.size.width/5.8, 50, 220, 2);
? ? ? ? ? ? }
? ? ? ? ? ? else{
? ? ? ? ? ? ? ? _line.frame = CGRectMake(self.view.frame.size.width/5.8, 50, 220, 2);
? ? ? ? ? ? }
? ? ? ? }];
? ? }];
}
//開啟關閉閃光燈
-(void)flashLightClick{
? ? AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
?? ?
? ? if (device.torchMode==AVCaptureTorchModeOff) {
? ? ? ? //閃光燈開啟
? ? ? ? [device lockForConfiguration:nil];
? ? ? ? [device setTorchMode:AVCaptureTorchModeOn];
? ? }else {
? ? ? ? //閃光燈關閉
? ? ? ??[device setTorchMode:AVCaptureTorchModeOff];
? ? }
}
?
- (void)viewDidLoad
{
?? ?
? ? //相機界面的定制在self.view上加載即可
? ? BOOL Custom= [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];//判斷攝像頭是否能用
? ? if (Custom) {
? ? ? ? [self initCapture];//啟動攝像頭
? ? }
? ? [self createView];
? ? [super viewDidLoad];
?? ?
}
#pragma mark 選擇相冊
- (void)pressPhotoLibraryButton:(UIButton *)button
{? if (timer) {
? ? [timer invalidate];
? ? timer=nil;
}
? ? _line.frame = CGRectMake(50, 50, 220, 2);
? ? num = 0;
? ? upOrdown = NO;
?
? ? UIImagePickerController *picker = [[UIImagePickerController alloc] init];
? ? picker.allowsEditing = YES;
? ? picker.delegate = self;
? ? picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
? ? [self presentViewController:picker animated:YES completion:^{
? ? ? ? self.isScanning = NO;
? ? ? ? [self.captureSession stopRunning];
? ? }];
}
#pragma mark 點擊取消
- (void)pressCancelButton:(UIButton *)button
{
? ? self.isScanning = NO;
? ? [self.captureSession stopRunning];
?? ?
? ? self.ScanResult(nil,NO);
? ? if (timer) {
? ? ? ? [timer invalidate];
? ? ? ? timer=nil;
? ? }
? ? _line.frame = CGRectMake(50, 50, 220, 2);
? ? num = 0;
? ? upOrdown = NO;
? ? [self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark 開啟相機
- (void)initCapture
{
? ? self.captureSession = [[AVCaptureSession alloc] init];
?? ?
? ? AVCaptureDevice* inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
?? ?
? ? AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:nil];
? ? [self.captureSession addInput:captureInput];
? ? AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc] init];
? ? captureOutput.alwaysDiscardsLateVideoFrames = YES;
? ??
? ? if (IOS7) {
? ? ? ? AVCaptureMetadataOutput*_output=[[AVCaptureMetadataOutput alloc]init];
? ? ? ? [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
? ? ? ? [self.captureSession setSessionPreset:AVCaptureSessionPresetHigh];
? ? ? ? [self.captureSession addOutput:_output];
? ? ? ? _output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode];
?? ? ? ?
? ? ? ? if (!self.captureVideoPreviewLayer) {
? ? ? ? ? ? self.captureVideoPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
? ? ? ? }
? ? ? ? // NSLog(@"prev %p %@", self.prevLayer, self.prevLayer);
? ? ? ? self.captureVideoPreviewLayer.frame = self.view.bounds;
? ? ? ? self.captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
? ? ? ? [self.view.layer addSublayer: self.captureVideoPreviewLayer];
? ? ? ? self.isScanning = YES;
? ? ? ? [self.captureSession startRunning];
? ? }else{
? ? ? ? [captureOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
?? ? ? ?
? ? ? ? NSString* key = (NSString *)kCVPixelBufferPixelFormatTypeKey;
? ? ? ? NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];
? ? ? ? NSDictionary *videoSettings = [NSDictionary dictionaryWithObject:value forKey:key];
? ? ? ? [captureOutput setVideoSettings:videoSettings];
? ? ? ? [self.captureSession addOutput:captureOutput];
?? ? ? ?
? ? ? ? NSString* preset = 0;
? ? ? ? if (NSClassFromString(@"NSOrderedSet") && // Proxy for "is this iOS 5" ...
? ? ? ? ? ? [UIScreen mainScreen].scale > 1 &&
? ? ? ? ? ? [inputDevice
?? ? ? ? ? ? supportsAVCaptureSessionPreset:AVCaptureSessionPresetiFrame960x540]) {
? ? ? ? ? ? ? ? // NSLog(@"960");
? ? ? ? ? ? ? ? preset = AVCaptureSessionPresetiFrame960x540;
? ? ? ? ? ? }
? ? ? ? if (!preset) {
? ? ? ? ? ? // NSLog(@"MED");
? ? ? ? ? ? preset = AVCaptureSessionPresetMedium;
? ? ? ? }
? ? ? ? self.captureSession.sessionPreset = preset;
?? ? ? ?
? ? ? ? if (!self.captureVideoPreviewLayer) {
? ? ? ? ? ? self.captureVideoPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
? ? ? ? }
? ? ? ? // NSLog(@"prev %p %@", self.prevLayer, self.prevLayer);
? ? ? ? self.captureVideoPreviewLayer.frame = self.view.bounds;
? ? ? ? self.captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
? ? ? ? [self.view.layer addSublayer: self.captureVideoPreviewLayer];
?? ? ? ?
? ? ? ? self.isScanning = YES;
? ? ? ? [self.captureSession startRunning];
?? ? }
}
- (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer
{
? ? CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
? ? // Lock the base address of the pixel buffer
? ? CVPixelBufferLockBaseAddress(imageBuffer,0);
?? ?
? ? // Get the number of bytes per row for the pixel buffer
? ? size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
? ? // Get the pixel buffer width and height
? ? size_t width = CVPixelBufferGetWidth(imageBuffer);
? ? size_t height = CVPixelBufferGetHeight(imageBuffer);
?? ?
? ? // Create a device-dependent RGB color space
? ? CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
? ? if (!colorSpace)
? ? {
? ? ? ? NSLog(@"CGColorSpaceCreateDeviceRGB failure");
? ? ? ? return nil;
? ? }
? ? // Get the base address of the pixel buffer
? ? void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
? ? // Get the data size for contiguous planes of the pixel buffer.
? ? size_t bufferSize = CVPixelBufferGetDataSize(imageBuffer);
?? ?
? ? // Create a Quartz direct-access data provider that uses data we supply
? ? CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, baseAddress, bufferSize,NULL);
? ? // Create a bitmap image from data supplied by our data provider
? ? CGImageRef cgImage =
? ? CGImageCreate(width,height,8,32,bytesPerRow,colorSpace,kCGImageAlphaNoneSkipFirst |kCGBitmapByteOrder32Little,provider,NULL,true,kCGRenderingIntentDefault);
? ? CGDataProviderRelease(provider);
? ? CGColorSpaceRelease(colorSpace);
? ? // Create and return an image object representing the specified Quartz image
? ? UIImage *image = [UIImage imageWithCGImage:cgImage];
? return image;
}
?#pragma mark 對圖像進行解碼
- (void)decodeImage:(UIImage *)image
{
? ??self.isScanning = NO;
? ? ZBarSymbol *symbol = nil;
? ? ZBarReaderController* read = [ZBarReaderController new];
? ? read.readerDelegate = self;
? ? CGImageRef cgImageRef = image.CGImage;
? ? for(symbol in [read scanImage:cgImageRef])break;
? ? if (symbol!=nil) {
? ? ? ? if (timer) {
? ? ? ? ? ? [timer invalidate];
? ? ? ? ? ? timer=nil;
? ? ? ? }
? ? ? ??_line.frame = CGRectMake(50, 50, 220, 2);
? ? ? ? num = 0;
? ? ? ? upOrdown = NO;
? ? ? ? self.ScanResult(symbol.data,YES);
? ? ? ? [self.captureSession stopRunning];
? ? ? ? [self dismissViewControllerAnimated:YES completion:nil];
? ? }else{
? ? ? ? timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(animation1) userInfo:nil repeats:YES];
? ? ? ? num = 0;
? ? ? ? upOrdown = NO;
? ? ? ? self.isScanning = YES;
? ? ? ? [self.captureSession startRunning];
? ? ? ??}
?}
#pragma mark - AVCaptureVideoDataOutputSampleBufferDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
? ? UIImage *image = [self imageFromSampleBuffer:sampleBuffer];
?? ?
? ? [self decodeImage:image];
}
#pragma mark AVCaptureMetadataOutputObjectsDelegate//IOS7下觸發
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
if (metadataObjects.count>0)
? ? {
? ? ? ? AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
? ? ? ? self.ScanResult(metadataObject.stringValue,YES);
? ? }
? ? [self.captureSession stopRunning];
? ? _line.frame = CGRectMake(50, 50, 220, 2);
? ? num = 0;
? ? upOrdown = NO;
? ? [self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - UIImagePickerControllerDelegate
?- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
? ? if (timer) {
? ? ? ? [timer invalidate];
? ? ? ? timer=nil;
? ? }
? ? _line.frame = CGRectMake(50, 50, 220, 2);
? ? num = 0;
? ? upOrdown = NO;
? ? UIImage *image = [info objectForKey:@"UIImagePickerControllerEditedImage"];
? ? [self dismissViewControllerAnimated:YES completion:^{[self decodeImage:image];}];
}
//相冊取消
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
? ? if (timer) {
? ? ? ? [timer invalidate];
? ? ? ? timer=nil;
? ? }
? ? _line.frame = CGRectMake(50, 50, 220, 2);
? ? num = 0;
? ? upOrdown = NO;
? ? timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(animation1) userInfo:nil repeats:YES];
? ? [self dismissViewControllerAnimated:YES completion:^{
? ? ? ? self.isScanning = YES;
? ? ? ? [self.captureSession startRunning];
? ? }];
}
?#pragma mark - DecoderDelegate
+(NSString*)zhengze:(NSString*)str
{
? ? ? NSError *error;
? ? //http+:[^\\s]* 這是檢測網址的正則表達式
? ? NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"http+:[^\\s]*" options:0 error:&error];//篩選
? ??? ? if (regex != nil) {
? ? ? ? NSTextCheckingResult *firstMatch = [regex firstMatchInString:str options:0 range:NSMakeRange(0, [str length])];
? ? ? ? if (firstMatch) {
? ? ? ? ? ? NSRange resultRange = [firstMatch rangeAtIndex:0];
? ? ? ? ? ? //從urlString中截取數據
? ? ? ? ? ? NSString *result1 = [str substringWithRange:resultRange];
? ? ? ? ? ? NSLog(@"正則表達后的結果%@",result1);
? ? ? ? ? ? return result1;? ? ? ? ? ??
? ? ? ? }
? ? }
? ? return nil;
}
?
?
效果圖:
?
開燈可以打開系統的手電筒,相冊可以進入系統相冊,如果選擇的圖片中包含有二維碼,既可以自動掃描!
?
如有問題可以評論提問,有評必回!!!
2015最后一天,祝大家新年快樂!記得給個贊哦^_^
?
轉載于:https://www.cnblogs.com/MasterPeng/p/5091630.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的二维码扫描利用ZBar实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 算法分类整理+模板①:矩阵快速幂
- 下一篇: 怎么下载全国水系图层