ios 二維碼識別功能

最近在做掃描二維碼相關功能,網上關於這方面的介紹比較少,就稍微總結了一下,希望對大家有所幫助;
1.使用系統的AVFoundation做的二維碼掃描器(iOS7以後),這方面的代碼還是比較多的,以下是借鑑的代碼。具體代碼,參照:http://www.jianshu.com/p/6b7d54b3f88b

-(void)setupCamera {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 耗時的操作
        // Device
        _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        
        // Input
        _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
        
        // Output
        _output = [[AVCaptureMetadataOutput alloc]init];
        //    [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
        [ _output setRectOfInterest : CGRectMake ((60+64)/SCREEN_HEIGHT ,40/SCREEN_WIDTH , SCAN_HEIGHT/SCREEN_HEIGHT , SCAN_HEIGHT/SCREEN_WIDTH )];//限制掃描區域
        [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
        
        // Session
        _session = [[AVCaptureSession alloc]init];
        [_session setSessionPreset:AVCaptureSessionPresetHigh];
        if ([_session canAddInput:self.input])
        {
            [_session addInput:self.input];
        }
        
        if ([_session canAddOutput:self.output])
        {
            [_session addOutput:self.output];
        }
        
        // 條碼類型 AVMetadataObjectTypeQRCode
        _output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode];
        dispatch_async(dispatch_get_main_queue(), ^{
            // 更新界面
            // Preview
            _preview =[AVCaptureVideoPreviewLayer layerWithSession:self.session];
            _preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
            //    _preview.frame =CGRectMake(20,110,280,280);
            _preview.frame = self.view.bounds;
            [self.view.layer insertSublayer:self.preview atIndex:0];
            // Start
            [_session startRunning];
        });
    });
}

注:關於掃描範圍,可參照http://www.2cto.com/kf/201411/356046.html,該作者有關於這部分的詳細解釋。

2.添加黑色透明背景,中間透明區域,用於掃描,主要思想是添加一個黑色半透明view,使用CGContextClearRect方法,將掃描範圍的正方形區域擦除。相關代碼如下:

-(void) drawViewForScan {
    ScanView* bgView = [[ScanView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)];
    [self.view addSubview:bgView ];
    
    //掃描區域
    UIView* scanView = [[UIView alloc] initWithFrame:CGRectMake (40 , 60 + 64 ,SCAN_HEIGHT, SCAN_HEIGHT )];
    scanView.backgroundColor = [UIColor clearColor];
    [scanView.layer setMasksToBounds:YES];
    [scanView.layer setBorderWidth:0.5];
    scanView.layer.borderColor = [UIColor whiteColor].CGColor;
    [self.view addSubview:scanView];
    
    float width = 8.0f;
    float height = 2.0f;
    //左上角邊框樣式
    UIView* LeftTopView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width+height, height)];
    LeftTopView.backgroundColor = [UIColor greenColor];
    [scanView addSubview:LeftTopView];
    UIView* LeftTopView2 = [[UIView alloc] initWithFrame:CGRectMake(0, height, height, width)];
    LeftTopView2.backgroundColor = [UIColor greenColor];
    [scanView addSubview:LeftTopView2];
    
    //右上角邊框樣式
    UIView* RightTopView = [[UIView alloc] initWithFrame:CGRectMake(SCAN_HEIGHT-width-height, 0, width+height, height)];
    RightTopView.backgroundColor = [UIColor greenColor];
    [scanView addSubview:RightTopView];
    UIView* RightTopView2 = [[UIView alloc] initWithFrame:CGRectMake(SCAN_HEIGHT-height, height, height, width)];
    RightTopView2.backgroundColor = [UIColor greenColor];
    [scanView addSubview:RightTopView2];
    
    //左下角邊框樣式
    UIView* LeftLowView = [[UIView alloc] initWithFrame:CGRectMake(0, SCAN_HEIGHT-width-height, height, width)];
    LeftLowView.backgroundColor = [UIColor greenColor];
    [scanView addSubview:LeftLowView];
    UIView* LeftLowView2 = [[UIView alloc] initWithFrame:CGRectMake(0, SCAN_HEIGHT-height, height+width, height)];
    LeftLowView2.backgroundColor = [UIColor greenColor];
    [scanView addSubview:LeftLowView2];
    
    //右下角邊框樣式
    UIView* RightLowView = [[UIView alloc] initWithFrame:CGRectMake(SCAN_HEIGHT-height, SCAN_HEIGHT-width-height, height, width)];
    RightLowView.backgroundColor = [UIColor greenColor];
    [scanView addSubview:RightLowView];
    UIView* RightLowView2 = [[UIView alloc] initWithFrame:CGRectMake(SCAN_HEIGHT-height-width, SCAN_HEIGHT-height, width+height, height)];
    RightLowView2.backgroundColor = [UIColor greenColor];
    [scanView addSubview:RightLowView2];
    
    _line = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"line.png"]];
    _line.frame = CGRectMake(0, 0, SCAN_HEIGHT, 2);
    [scanView addSubview:_line];
}

CGContextClearRect方法在ScanView(黑色背景View,繼承一個UIView就可以)的- (void)drawRect:(CGRect)rect方法裏,相關代碼如下:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGRect drawRect = CGRectMake (40 , 60 + 64 , SCREEN_WIDTH-80 , SCREEN_WIDTH-80 );
    CGContextClearRect(context, drawRect);  //clear the center rect  of the layer
}

- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {        //2
        self.backgroundColor = [UIColor colorWithRed:0.0/255.0 green:0.0/255.0 blue:0.0/255.0 alpha:0.5];
        
        UILabel * labIntroudction= [[UILabel alloc] initWithFrame:CGRectMake(50, 60+64+SCAN_HEIGHT, SCAN_HEIGHT-10, 20)];
        labIntroudction.backgroundColor = [UIColor clearColor];
        //labIntroudction.numberOfLines=2;
        labIntroudction.font = [UIFont systemFontOfSize:14.0f];
        labIntroudction.textColor=[UIColor whiteColor];
        labIntroudction.text=@"將二維碼/條碼放入框內,即可自動掃描";
        [labIntroudction sizeToFit];
        labIntroudction.center = CGPointMake(self.bounds.size.width/2,60+64+SCAN_HEIGHT+15);

        [self addSubview:labIntroudction];
    }
      return self;
}

注:關於掃描區域的樣式,即四個角都有綠色邊角,也可以使用UIImageView,採用圖片即可。

3.添加掃描動畫效果,相關代碼如下:

- (void)viewDidLoad添加定時器初始化部分的代碼,如下:

 upOrdown = NO;
    num =0;
    timer = [NSTimer scheduledTimerWithTimeInterval:.02 target:self selector:@selector(animation1) userInfo:nil repeats:YES];

定時器動畫代碼:

-(void)animation1 {
    if (upOrdown == NO) {
        num++;
        _line.frame = CGRectMake(0, num, SCAN_HEIGHT, 2);
        if (num == SCAN_HEIGHT) {
            num=0;
        }
    }
}

4.掃描成功事件響應,處理掃描結果。

#pragma mark AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    NSString *stringValue;
    if ([metadataObjects count] >0) {
        AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
        stringValue = metadataObject.stringValue;//掃描最終結果
    }
    
    [_session stopRunning];
    
    [timer invalidate];
    [self joinOrg:stringValue];//連接api方法
}

以上就是相關步驟以及代碼,因爲網上實在相關代碼太少,儘管我寫的不是太好,也希望幫到別人,由於經驗不足,可能有的地方寫的不到位,希望指正。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章