掃描功能小結 (掃描二維碼、條碼),掃描功能小結條碼

來源:互聯網
上載者:User

掃描功能小結 (掃描二維碼、條碼),掃描功能小結條碼

此次掃碼功能以iOS系統原生的AVFoundation架構為基礎。

廢話不多說,直接上代碼

#import <UIKit/UIKit.h>@interface ScanViewController : UIViewController@end
建立掃描介面

在.m檔案中建立對象

#import "ScanViewController.h"#import <AVFoundation/AVFoundation.h>#import "UserInputCodeViewController.h"#import "ScanResultViewController.h"@interface ScanViewController ()<AVCaptureMetadataOutputObjectsDelegate>@property (nonatomic, strong) AVCaptureDevice *device;@property (nonatomic, strong) AVCaptureDeviceInput *input;@property (nonatomic, strong) AVCaptureMetadataOutput *output;@property (nonatomic, strong) AVCaptureSession *session;@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;/*** 專門用於儲存描邊的圖層 ***/@property (nonatomic,strong) CALayer *containerLayer;/** 掃描範圍 */@property(nonatomic, strong) UIView *scanFrame;@property(nonatomic, strong) UIView *line;//@property (nonatomic, strong) UIImageView *scanArea;@property (nonatomic, strong) UILabel *lightLb;/** 是否開啟燈光 */@property (nonatomic, assign) BOOL isLightOn;@end@implementation ScanViewController-(void)viewWillAppear:(BOOL)animated {    [super viewWillAppear:animated];    if (!_session ) {        [self startScan];    }    [self refreshScanLineAnimation];}-(void)refreshScanLineAnimation {    if (_line) {        [self scanLineAnimate];    }}- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view.    self.title = @"掃碼開鎖";    self.view.backgroundColor = [UIColor whiteColor];        _isLightOn = NO;        [self initViews];        [self initConner];        [self startScan];}-(void)initViews {    CGRect frame = CGRectZero;        frame.origin.x = (SCREEN_WIDTH - 230) / 2;    frame.origin.y = (SCREEN_HEIGHT - 500) / 2;    frame.size.width = 230;    frame.size.height= 230;        UIView* view = [[UIView alloc] initWithFrame:frame];    view.backgroundColor= [UIColor clearColor];    view.layer.borderWidth = 1;    view.layer.borderColor = [[UIColor grayColor] CGColor];    self.scanFrame = view;    [self.view addSubview:view];        //top    UIView* shadow = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, view.frame.origin.y)];    shadow.backgroundColor = [UIColor blackColor];    shadow.alpha = 0.5;    [self.view addSubview:shadow];        //bottom    shadow = [[UIView alloc] initWithFrame:CGRectMake(0, view.frame.origin.y + view.frame.size.height, SCREEN_WIDTH, SCREEN_HEIGHT - (view.frame.origin.y + view.frame.size.height))];    shadow.backgroundColor = [UIColor blackColor];    shadow.alpha = 0.5;    [self.view addSubview:shadow];        //left    shadow = [[UIView alloc] initWithFrame:CGRectMake(0, view.frame.origin.y, (SCREEN_WIDTH - view.frame.size.width) / 2, view.frame.size.height)];    shadow.backgroundColor = [UIColor blackColor];    shadow.alpha = 0.5;    [self.view addSubview:shadow];        //right    shadow = [[UIView alloc] initWithFrame:CGRectMake(view.frame.origin.x + view.frame.size.width, view.frame.origin.y, (SCREEN_WIDTH - view.frame.size.width) / 2, view.frame.size.height)];    shadow.backgroundColor = [UIColor blackColor];    shadow.alpha = 0.5;    [self.view addSubview:shadow];        _line = [[UIView alloc] initWithFrame:CGRectMake(view.frame.origin.x + 1, view.frame.origin.y + 1, frame.size.width - 2, 3)];    _line.backgroundColor = UIColorFromRGB(0x28a0f0);    [self.view addSubview:_line];        UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(view.frame) + HEIGTHCUSTOME(70), _line.frame.size.width, 15)];    label.font = UIFontWithPX(26);    label.textColor = [UIColor whiteColor];    label.textAlignment = NSTextAlignmentCenter;    label.center = CGPointMake(_line.center.x, label.center.y);    label.text = @"請對準充電箱上的二維碼";    [self.view addSubview:label];        //light    UIButton* light = [UIButton buttonWithType:UIButtonTypeCustom];    light.frame = CGRectMake(0, view.frame.origin.y + view.frame.size.height + 120, 100, 100);//    light.center = CGPointMake(view.frame.origin.x + view.frame.size.width - 50, light.center.y);    light.center = CGPointMake(view.center.x, light.center.y);    light.backgroundColor = [UIColor clearColor];    [light setImage:IMAGE(@"flashlight_off") forState:UIControlStateNormal];    [light addTarget:self action:@selector(openLight:) forControlEvents:UIControlEventTouchUpInside];    [self.view addSubview:light];        _lightLb = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 20)];    _lightLb.center = CGPointMake(light.center.x, light.center.y + 50);    _lightLb.text = @"開啟手電筒";    _lightLb.textAlignment = NSTextAlignmentCenter;    _lightLb.textColor = [UIColor whiteColor];    _lightLb.font = [UIFont systemFontOfSize:14];    [self.view addSubview:_lightLb];}- (void)initConner {    CGFloat w = 2;    CGFloat h = 10;    CGFloat d = 2;    CGPoint point = CGPointZero;        //left - top    point = CGPointMake(_scanFrame.frame.origin.x - w - d, _scanFrame.frame.origin.y - w - d);    UIView* view = [[UIView alloc] initWithFrame:CGRectMake(point.x, point.y, w, h)];    view.backgroundColor = UIColorFromRGB(0x28a0f0);    [self.view addSubview:view];        view = [[UIView alloc] initWithFrame:CGRectMake(point.x, point.y, h, w)];    view.backgroundColor = UIColorFromRGB(0x28a0f0);    [self.view addSubview:view];        //left - down    point = CGPointMake(_scanFrame.frame.origin.x - w - d, _scanFrame.frame.origin.y + _scanFrame.frame.size.height + d + w - h);    view = [[UIView alloc] initWithFrame:CGRectMake(point.x, point.y, w, h)];    view.backgroundColor = UIColorFromRGB(0x28a0f0);    [self.view addSubview:view];        point = CGPointMake(point.x, _scanFrame.frame.origin.y + _scanFrame.frame.size.height + d);    view = [[UIView alloc] initWithFrame:CGRectMake(point.x, point.y, h, w)];    view.backgroundColor = UIColorFromRGB(0x28a0f0);    [self.view addSubview:view];        //right - top    point = CGPointMake(_scanFrame.frame.origin.x + _scanFrame.frame.size.width + d, _scanFrame.frame.origin.y - w - d);    view = [[UIView alloc] initWithFrame:CGRectMake(point.x, point.y, w, h)];    view.backgroundColor = UIColorFromRGB(0x28a0f0);    [self.view addSubview:view];        point = CGPointMake(_scanFrame.frame.origin.x + _scanFrame.frame.size.width + w + d - h, point.y);    view = [[UIView alloc] initWithFrame:CGRectMake(point.x, point.y, h, w)];    view.backgroundColor = UIColorFromRGB(0x28a0f0);    [self.view addSubview:view];        //right - down    point = CGPointMake(_scanFrame.frame.origin.x + _scanFrame.frame.size.width + d, _scanFrame.frame.origin.y + _scanFrame.frame.size.height + w + d - h);    view = [[UIView alloc] initWithFrame:CGRectMake(point.x, point.y, w, h)];    view.backgroundColor = UIColorFromRGB(0x28a0f0);    [self.view addSubview:view];        point = CGPointMake(point.x + w - h, _scanFrame.frame.origin.y + _scanFrame.frame.size.height + d);    view = [[UIView alloc] initWithFrame:CGRectMake(point.x, point.y, h, w)];    view.backgroundColor = UIColorFromRGB(0x28a0f0);    [self.view addSubview:view];}- (void)scanLineAnimate {    [UIView beginAnimations:nil context:nil];    [UIView setAnimationDuration:2];    [UIView setAnimationCurve:UIViewAnimationCurveLinear];    [UIView setAnimationRepeatAutoreverses:YES];    [UIView setAnimationRepeatCount:HUGE_VALF];    _line.center = CGPointMake(_line.center.x, _scanFrame.frame.origin.y + _scanFrame.frame.size.height - 5);    [UIView commitAnimations];}- (void)openLight:(UIButton*)sender {    [_device lockForConfiguration:nil];    if (!sender.selected) {        [sender setImage:IMAGE(@"flashlight_on") forState:UIControlStateNormal];        [_device setTorchMode:AVCaptureTorchModeOn];        [_device setFlashMode:AVCaptureFlashModeOn];        _lightLb.text = @"關閉手電筒";        sender.selected = YES;    } else {        [sender setImage:IMAGE(@"flashlight_off") forState:UIControlStateNormal];        [_device setTorchMode:AVCaptureTorchModeOff];        [_device setFlashMode:AVCaptureFlashModeOff];        _lightLb.text = @"開啟手電筒";        sender.selected = NO;    }    [_device unlockForConfiguration];}- (void)startScan {    if (![self.session canAddInput:self.input]) return;    [self.session addInput:self.input];        if (![self.session canAddOutput:self.output]) return;    [self.session addOutput:self.output];    //    self.output.metadataObjectTypes = self.output.availableMetadataObjectTypes;     // 如此設定,可掃描二維碼、條碼    [self.output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];        [self.output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];        [self.view.layer insertSublayer:self.previewLayer atIndex:0];        [self.view.layer addSublayer:self.containerLayer];       [self.session startRunning];}- (void)drawLine:(AVMetadataMachineReadableCodeObject *)objc {    NSArray *array = objc.corners;        CAShapeLayer *layer = [[CAShapeLayer alloc] init];    layer.lineWidth = 2;    layer.strokeColor = [UIColor greenColor].CGColor;    layer.fillColor = [UIColor clearColor].CGColor;        UIBezierPath *path = [[UIBezierPath alloc] init];    CGPoint point = CGPointZero;    int index = 0;        CFDictionaryRef dict = (__bridge CFDictionaryRef)(array[index++]);    CGPointMakeWithDictionaryRepresentation(dict, &point);        [path moveToPoint:point];        for (int i = 1; i<array.count; i++) {        CGPointMakeWithDictionaryRepresentation((__bridge CFDictionaryRef)array[i], &point);        [path addLineToPoint:point];    }    [path closePath];    layer.path = path.CGPath;    [self.containerLayer addSublayer:layer];}- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {    if (_session) {        [_session stopRunning];    }    [_output setMetadataObjectsDelegate:nil queue:dispatch_get_main_queue()];        // id 類型不能點文法,所以要先去取出數組中對象    id object = [metadataObjects lastObject];    if ([object isKindOfClass:[AVMetadataMachineReadableCodeObject class]]) {        NSString *stringValue;        if ([metadataObjects count] >0) {            AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects lastObject];            stringValue = metadataObject.stringValue;        }                [self judgeCode:stringValue];//        [self judgeCode:@"test00001"];                [self clearLayers];        AVMetadataMachineReadableCodeObject *obj = (AVMetadataMachineReadableCodeObject *)[self.previewLayer transformedMetadataObjectForMetadataObject:object];        [self drawLine:obj];    }}// 初始化掃描介面-(void)initPreviewImg {    [_output setMetadataObjectsDelegate:nil queue:dispatch_get_main_queue()];    [_session stopRunning];    [_session removeOutput:_output];    [_session removeInput:_input];        [_containerLayer removeFromSuperlayer];    [_previewLayer removeFromSuperlayer];        _containerLayer = nil;       //不置空,二維碼的彩色邊框無法去除    _session = nil;                 // 不置空,返回本頁面,出現白屏    _output = nil;    _previewLayer = nil;        // 不置空,會有null 指標,由下個介面返回時會出現崩潰    /*     Assertion failed: (_inputInternal->figCaptureSession == NULL), function __44-[AVCaptureInput attachToFigCaptureSession:]_block_invoke, file /BuildRoot/Library/Caches/com.apple.xbs/Sources/EmbeddedAVFoundation/EmbeddedAVFoundation-1184.7/Aspen/AVCaptureInput.m, line 132.     */}- (void)clearLayers {    if (self.containerLayer.sublayers) {        for (CALayer *subLayer in self.containerLayer.sublayers) {            [subLayer removeFromSuperlayer];        }    }}#pragma mark -------- 懶載入---------- (AVCaptureDevice *)device {    if (_device == nil) {        _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];    }    return _device;}- (AVCaptureDeviceInput *)input {    if (_input == nil) {        _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];    }    return _input;}- (AVCaptureSession *)session {    if (_session == nil) {        _session = [[AVCaptureSession alloc] init];    }    return _session;}- (AVCaptureVideoPreviewLayer *)previewLayer {    if (_previewLayer == nil) {        _previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];        _previewLayer.frame = self.view.bounds;    }    return _previewLayer;}- (AVCaptureMetadataOutput *)output {    if (_output == nil) {        _output = [[AVCaptureMetadataOutput alloc] init];        CGRect viewRect = self.view.frame;        CGRect containerRect = _scanFrame.frame;        CGFloat x = containerRect.origin.y / viewRect.size.height;        CGFloat y = containerRect.origin.x / viewRect.size.width;        CGFloat width = containerRect.size.height / viewRect.size.height;        CGFloat height = containerRect.size.width / viewRect.size.width;        _output.rectOfInterest = CGRectMake(x, y, width, height);    }    return _output;}- (CALayer *)containerLayer {    if (_containerLayer == nil) {        _containerLayer = [[CALayer alloc] init];        _containerLayer.frame = self.view.bounds;    }    return _containerLayer;}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}@end
建立對象

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.