iOS 二维码、条码扫描(带UI)

来源:互联网 发布:ssm 怎么打印sql 编辑:程序博客网 时间:2024/05/01 18:12
下面代码中待解决的问题:扫码过程中被打断(如按Home键),扫描动画会停止,需要做相应处理,在恢复前台时恢复动画。摄像头扫码使用iOS原生框架,从图片导入识别二维码使用ZXingObjC框架
//
//  BarCodeViewController.h
// 
//
//  Created by pilgrim on 16/5/11.
//  Copyright © 2016pilgrim. All rights reserved.
//

#import<UIKit/UIKit.h>

@interfaceBarCodeViewController :UIViewController

@end

//
//  BarCodeViewController.m
// 
//
//  Created by pilgrim on 16/5/11.
//  Copyright © 2016pilgrim. All rights reserved.
//

#import"BarCodeViewController.h"
#import
<AVFoundation/AVFoundation.h>
#import
<ZXingObjC.h>
#import
"HomePageViewController.h"

@interfaceBarCodeViewController ()<AVCaptureMetadataOutputObjectsDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate>


@property(weak,nonatomic)IBOutlet UIView *coverView;
//从相册导入
@property(weak,nonatomic)IBOutlet UIButton *photoBtn;
//灯光按钮
@property(weak,nonatomic)IBOutlet UIButton *lightBtn;

//摄像头设备
@property( strong , nonatomic ) AVCaptureDevice * device;
//输入流
@property( strong , nonatomic ) AVCaptureDeviceInput * input;
//输出流
@property( strong , nonatomic ) AVCaptureMetadataOutput * output;
//session
@property( strong , nonatomic ) AVCaptureSession * session;
//预览图层
@property( strong , nonatomic ) AVCaptureVideoPreviewLayer * preview;

//图片选择器
@property(nonatomic,strong)UIImagePickerController * imagePicker;
//蒙版图层
@property(nonatomic,strong)CALayer * coverLayer;
//刷新线
@property(nonatomic,strong)UIImageView * lineIV;

@end

@implementationBarCodeViewController

#pragma mark -生命周期
- (void)viewDidLoad {
    [
superviewDidLoad];
   
   
//设备
   
self.device= [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];
   
   
//输入流
   
NSError * error = nil;
   
self.input= [AVCaptureDeviceInputdeviceInputWithDevice:self.deviceerror:&error];
   
if (error) {
       
NSLog(@"输入流创建报错");
       
return;
    }
   
   
//输出流
   
self.output= [[AVCaptureMetadataOutputalloc]init];
    [
self.outputsetMetadataObjectsDelegate:selfqueue:dispatch_get_main_queue()];
   
   
//session
   
self.session= [[AVCaptureSessionalloc]init];
    [
self.sessionsetSessionPreset:AVCaptureSessionPresetHigh];
   
   
if ([self.sessioncanAddInput:self.input]) {
        [
self.sessionaddInput:self.input];
    }
   
   
if ([self.sessioncanAddOutput:self.output]) {
        [
self.sessionaddOutput:self.output];
    }
   
   
self.output.metadataObjectTypes= [NSArrayarrayWithObjects:AVMetadataObjectTypeEAN13CodeAVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeCode128Code,AVMetadataObjectTypeQRCode,nil];
   
//扫描区域
   
self.output.rectOfInterest= CGRectMake((float)((YJScreenHeight- 64) /2 -120) / (float)(YJScreenHeight- 64), (float)(YJScreenWidth/ 2 -120) / (float)YJScreenWidth,240.0 / (float)(YJScreenHeight- 64),240.0 / (float)YJScreenWidth);
   
   
//preview
   
self.preview= [AVCaptureVideoPreviewLayerlayerWithSession:self.session];
   
self.preview.videoGravity= AVLayerVideoGravityResizeAspectFill;
   
self.preview.backgroundColor= [[UIColorblackColor]colorWithAlphaComponent:0.4].CGColor;
   
self.preview.frame= CGRectMake(0,0, [UIScreenmainScreen].bounds.size.width, [UIScreenmainScreen].bounds.size.height- 64);
    [
self.view.layerinsertSublayer:self.previewatIndex:0];
   
   
   
   
self.coverView.backgroundColor= [[UIColorblackColor]colorWithAlphaComponent:0.5];
   
UIBezierPath *path = [UIBezierPathbezierPathWithRect:CGRectMake(0,0,YJScreenWidth,YJScreenHeight)];
    [path
appendPath:[[UIBezierPathbezierPathWithRoundedRect:CGRectMake(YJScreenWidth/ 2 -120, (YJScreenHeight- 64) /2 -120,240,240)cornerRadius:0]bezierPathByReversingPath]];
   
CAShapeLayer * maskLayer = [CAShapeLayerlayer];
    maskLayer.
backgroundColor= [UIColorwhiteColor].CGColor;
    maskLayer.
path= path.CGPath;
   
self.coverView.layer.mask= maskLayer;
   
//    [self.view.layer insertSublayer:coverLayer atIndex:0];
}

- (
void)viewDidAppear:(BOOL)animated
{
#warning Need To Fix
   //检测灯的状态,然后改按钮的状态
   
if (self.session!= nil) {
       
if (self.session.isRunning== NO) {
            [
self.sessionstartRunning];
            [
selfshowAnimation];
           
if (self.coverLayer!= nil) {
                [
UIViewanimateWithDuration:0.5animations:^{
                   
self.coverLayer.backgroundColor= [[UIColorblackColor]colorWithAlphaComponent:0].CGColor;
                }
completion:^(BOOLfinished) {
                    [
self.coverLayerremoveFromSuperlayer];
                   
self.coverLayer= nil;
                }];
            }
        }
    }
    [
superviewDidAppear:animated];
}

- (
void)viewDidDisappear:(BOOL)animated
{
    [
self.sessionstopRunning];
    [
selfstopAnimation];
   
self.coverLayer= [CALayerlayer];
   
self.coverLayer.frame= CGRectMake(0,0,YJScreenWidth,YJScreenHeight);
   
self.coverLayer.backgroundColor= [[UIColorblackColor]colorWithAlphaComponent:0.8].CGColor;
    [
self.view.layeraddSublayer:self.coverLayer];
    [
superviewDidDisappear:animated];
}

#pragma mark -按钮点击事件
/**
 * 
从相册导入按钮点击事件
 *
 *  @param sender
按钮
 */

- (
IBAction)photoBtnDidClick:(UIButton*)sender {
   
self.imagePicker= [[UIImagePickerControlleralloc]init];
   
self.imagePicker.delegate= self;
   
self.imagePicker.allowsEditing= YES;
   
self.imagePicker.sourceType= UIImagePickerControllerSourceTypePhotoLibrary;
    [
self.navigationControllerpresentViewController:self.imagePickeranimated:YEScompletion:^{
    }];
}

/**
 * 
闪光灯按钮点击事件
 *
 *  @param sender
按钮
 */

- (
IBAction)lightBtnDidClick:(UIButton*)sender {
   
BOOL isLightOpened = [selfisLightOpened];
   
   
if (isLightOpened) {
        [sender
setTitle:@"开灯"forState:UIControlStateNormal];
    }
   
else
    {
        [sender
setTitle:@"关灯"forState:UIControlStateNormal];
    }
   
    [
selfopenLight:!isLightOpened];
}

//闪光灯
- (
BOOL)isLightOpened
{
   
if (![self.devicehasTorch]) {
       
return NO;
    }
else{
       
if ([self.devicetorchMode] ==AVCaptureTorchModeOn) {
           
return YES;
        }
else {
           
return NO;
        }
    }
}

- (
void)openLight:(BOOL)open
{
   
if (![self.devicehasTorch]) {
    }
else {
       
if (open) {
           
// 开启闪光灯
           
if(self.device.torchMode!= AVCaptureTorchModeOn ||
              
self.device.flashMode!= AVCaptureFlashModeOn){
                [
self.devicelockForConfiguration:nil];
                [
self.devicesetTorchMode:AVCaptureTorchModeOn];
                [
self.devicesetFlashMode:AVCaptureFlashModeOn];
                [
self.deviceunlockForConfiguration];
            }
        }
else {
           
// 关闭闪光灯
           
if(self.device.torchMode!= AVCaptureTorchModeOff ||
              
self.device.flashMode!= AVCaptureFlashModeOff){
                [
self.devicelockForConfiguration:nil];
                [
self.devicesetTorchMode:AVCaptureTorchModeOff];
                [
self.devicesetFlashMode:AVCaptureFlashModeOff];
                [
self.deviceunlockForConfiguration];
            }
        }
    }
}

//扫描动画
- (
void)showAnimation
{
   
if (self.lineIV== nil) {
       
self.lineIV= [[UIImageViewalloc]initWithFrame:CGRectMake(YJScreenWidth/ 2 -120, (YJScreenHeight- 64) /2 -120,240,2)];
       
self.lineIV.backgroundColor= [UIColorgreenColor];
        [
self.viewaddSubview:self.lineIV];
       
       
CABasicAnimation * animate = [CABasicAnimationanimationWithKeyPath:@"position"];
        animate.
fromValue= [NSValuevalueWithCGPoint:CGPointMake(YJScreenWidth/ 2, (YJScreenHeight- 64) /2 -120)];
        animate.
toValue= [NSValuevalueWithCGPoint:CGPointMake(YJScreenWidth/ 2, (YJScreenHeight- 64) /2 +120)];
        animate.
duration= 3.0;
        animate.
repeatCount= INT_MAX;
        [
self.lineIV.layeraddAnimation:animateforKey:nil];
    }
}

- (
void)stopAnimation
{
   
if (self.lineIV) {
        [
self.lineIV.layerremoveAllAnimations];
        [
self.lineIVremoveFromSuperview];
       
self.lineIV= nil;
    }
}

#pragma mark AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput*)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection*)connection
{
   
NSString *stringValue;
   
if ([metadataObjectscount] >0)
    {
       
AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
        stringValue = metadataObject.
stringValue;
       
NSLog(@"stringValue:%@", stringValue);
        [
self.sessionstopRunning];
        [
selfstopAnimation];
       
HomePageViewController * nextVC = [[HomePageViewControlleralloc]initWithNibName:@"HomePageViewController"bundle:nil];
        [
self.navigationControllerpushViewController:nextVCanimated:YES];
       
//        DetailViewController * detailVC = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
//        detailVC.detailURLStr = stringValue;
//        [self.navigationController pushViewController:detailVC animated:YES];
    }
}

#pragma mark - UIImagePickerViewControllerDelegate
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString*,id> *)info
{
   
UIImage * image = info[UIImagePickerControllerEditedImage];
   
NSLog(@"image:%@", image);
   
    [
self.navigationControllerdismissViewControllerAnimated:YEScompletion:^{
       
       
self.imagePicker= nil;
       
       
CGImageRef imageToDecode = image.CGImage// Given a CGImage in which we are looking for barcodes
       
       
ZXLuminanceSource *source = [[ZXCGImageLuminanceSourcealloc]initWithCGImage:imageToDecode];
       
ZXBinaryBitmap *bitmap = [ZXBinaryBitmapbinaryBitmapWithBinarizer:[ZXHybridBinarizerbinarizerWithSource:source]];
       
       
NSError *error = nil;
       
       
// There are a number of hints we can give to the reader, including
       
// possible formats, allowed lengths, and the string encoding.
       
ZXDecodeHints *hints = [ZXDecodeHintshints];
       
       
ZXMultiFormatReader *reader = [ZXMultiFormatReaderreader];
       
ZXResult *result = [reader decode:bitmap
                                   
hints:hints
                                   
error:&error];
       
if (result) {
           
// The coded result as a string. The raw data can be accessed with
           
// result.rawBytes and result.length.
           
NSString *contents = result.text;
           
NSLog(@"result:%@", contents);
           
HomePageViewController * nextVC = [[HomePageViewControlleralloc]initWithNibName:@"HomePageViewController"bundle:nil];
            [
self.navigationControllerpushViewController:nextVCanimated:YES];
           
           
// The barcode format, such as a QR code or UPC-A
           
//        ZXBarcodeFormat format = result.barcodeFormat;
        }
else {
            [
selfshowHUDInWindowJustWithText:@"未发现条码"disMissAfterDelay:1.0];
           
// Use error to determine why we didn't get a result, such as a barcode
           
// not being found, an invalid checksum, or a format inconsistency.
        }
    }];
   
   
}

- (
void)didReceiveMemoryWarning {
    [
superdidReceiveMemoryWarning];
   
// Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/


@end
0 0