规定区域二维码扫描,支持手电筒功能

最近项目遇到的需求:特定区域扫瞄并识别二维码,支持手电筒功能。好记性不如烂笔头,写下来方便后面自己用到。

1.动画部分,这部分可根据自己需要添加(不做过多描述)。

2.开启摄像头。iOS 10相机权限访问添在info.plist加Privacy - Camera Usage Description即可。

#define Height [UIScreen mainScreen].bounds.size.height //屏幕高

#define Width [UIScreen mainScreen].bounds.size.width //屏幕宽

#import <AVFoundation/AVFoundation.h>

@property(nonatomic,strong)AVCaptureSession *session;//输入输出的中间桥梁

@property (nonatomic,strong)AVCaptureVideoPreviewLayer *previewLayer;//相机实时预览图层

@property (nonatomic,strong)AVCaptureDevice *device;//用于获取相机的一些属性

@property (nonatomic,strong)CALayer * maskLayer;//扫描器灰色蒙板。


3.实现扫描功能

#pragma mark - 开始扫描二维码

- (void)startScanWithSize:(CGRect)frame

{

    //获取摄像设备

    if (self.device ==nil) {

        self.device = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];

    }

    //创建输入流

    AVCaptureDeviceInput *input = [AVCaptureDeviceInputdeviceInputWithDevice:self.deviceerror:nil];

    //判断输入流是否可用

    if (input) {

        //创建输出流

        AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutputalloc]init];

        //***设置代理,在主线程里刷新,注意此时self需要设置AVCaptureMetadataOutputObjectsDelegate协议***

        [output setMetadataObjectsDelegate:selfqueue:dispatch_get_main_queue()];

        //初始化连接对象

        if (self.session ==nil) {

            self.session = [[AVCaptureSessionalloc]init];

        }

        //高质量采集率

        [_sessionsetSessionPreset:AVCaptureSessionPresetHigh];

        [_sessionaddInput:input];

        [_sessionaddOutput:output];

        //设置扫码支持的编码格式(如下设置条形码和二维码兼容)

        output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code,AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeCode128Code];

        

        //扫描区域大小的设置:(这部分也可以自定义,显示自己想要的布局)

        self.previewLayer = [AVCaptureVideoPreviewLayerlayerWithSession:_session];

        self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

        self.previewLayer.frame = frame;//传入的相机预览图层大小(一般全屏)视情况而定

        [self.view.layerinsertSublayer:self.previewLayeratIndex:0];

        

        // 蒙版

        self.maskLayer = [[CALayeralloc]init];

        self.maskLayer.frame = CGRectMake(0,0, SCREEN_WIDTH,SCREEN_HEIGHT-64);

        self.maskLayer.delegate =self;

        [self.view.layerinsertSublayer:self.maskLayerabove:self.previewLayer];

        [self.maskLayersetNeedsDisplay];

        

        

        // 1.获取屏幕的frame

        CGRect viewRect =CGRectMake(0,0, SCREEN_WIDTH,SCREEN_HEIGHT);

        // 2.获取扫描容器的frame

        CGRect containerRect =imageView.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);//坐标取值范围(0~1)整个屏幕(0,0,1,1);

    }

}

然后:

    //开始捕获图像:这步才开始

    [_sessionstartRunning];

#pragma mark - 扫面结果在这个代理方法里获取到

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{


      AVMetadataMachineReadableCodeObject *metaDataObject = [metadataObjectsobjectAtIndex:0];

      NSString *valueStr = metaDataObject.stringValue;

      //获取到信息后停止扫描:

      [_sessionstopRunning];

      //输出扫描字符串:

      //NSLog(@"输出扫描字符串--%@ %@", valueStr);

}

//Note: 蒙板生成。需设置代理,并在退出页面时取消代理。

-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{

    if (layer ==self.maskLayer) {

        UIGraphicsBeginImageContextWithOptions(self.maskLayer.frame.size,NO, 1.0);

        CGContextSetFillColorWithColor(ctx, [UIColorcolorWithRed:0green:0blue:0alpha:0.6].CGColor);

        CGContextFillRect(ctx,self.maskLayer.frame);

        CGRect scanFrame = [self.viewconvertRect:imageView.framefromView:imageView.superview];//裁剪 imageView 扫描框

        CGContextClearRect(ctx, scanFrame);

    }

}

--分---------------割--------------------线--

4.手电筒按钮事件

- (void)openLight:(UIButton *)sender{

    sender.selected = !sender.selected;

    AVCaptureDevice *device =self.device;

    //修改前必须先锁定

    [self.devicelockForConfiguration:nil];

    //必须判定是否有闪光灯,否则如果没有闪光灯会崩溃

    if ([self.devicehasFlash]) {

        if (self.device.flashMode == AVCaptureFlashModeOff) {

            self.device.flashMode = AVCaptureFlashModeOn;

            self.device.torchMode = AVCaptureTorchModeOn;

        } elseif (self.device.flashMode ==AVCaptureFlashModeOn) {

            self.device.flashMode = AVCaptureFlashModeOff;

            self.device.torchMode = AVCaptureTorchModeOff;

        }

    }

    [device unlockForConfiguration];

}

5.结尾下图是成果(略丑...)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值