使用AVFoundation实现iOS原生二维码、条形码扫描(可限制扫描范围、可手动调节焦距)

第一次写博客,没有经验,有不正确或不规范的地方,希望大家不吝赐教。多谢支持!

最近需要做一个二维码扫描功能,在网上找了很多资料,有两个比较有名气的第三方框架:ZXingZBar。这两个框架都算比较成熟的了,使用度也很广,现在也都支持64位了。但我个人有点强迫症的,就是尽量不选择使用第三方框架,以免失去主动权(个人喜好),于是找到了AVFoundation,iOS7及以后的系统都可以支持,而且据说效率比第三方高,Perfect!

废话不多说,上代码吧!

一. 设置摄像头

<span style="font-size:18px;">- (void)setCamara
{
    AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error;
    
    // input
    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
    if (error) {
        NSLog(@"%@",error.description);
        return;
    }
    
    // session
    _captureSession = [[AVCaptureSession alloc] init];
    [_captureSession addInput:deviceInput];
    
    // output
    _output = [[AVCaptureMetadataOutput alloc] init];
    [_captureSession addOutput:_output];
    
    // 根据苹果的文档,这个队列必须是串行的
    [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    /*
     // 也可以创建一个新线程
     dispatch_queue_t dispatchQueue;
     dispatchQueue = dispatch_queue_create("myQueue", NULL);
     [_output setMetadataObjectsDelegate:self queue:dispatchQueue];
     */
    
    if ([_output.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeQRCode]) {
        if (self.bouth1D2D) { //同时需要支持条形码
            _output.metadataObjectTypes = @[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeQRCode];
        } else { //只支持二维码
            _output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode];
        }
    }
    
    // videoPreviewLayer在屏幕上显示摄像头捕获到的图像
    _videoPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_captureSession];
    
    //    videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    _videoPreviewLayer.videoGravity = AVLayerVideoGravityResize; // 需要调节焦距的设置
    
    _videoPreviewLayer.frame = self.view.layer.bounds;
    [self.view.layer addSublayer:_videoPreviewLayer];
    
    // connection(调节焦距使用)
    _connection = [_output connectionWithMediaType:AVMediaTypeVideo];
    
    // 开始扫描
    [_captureSession startRunning];
    
}</span>
需要注意的是: metadataObjectTypes 必须在 addOutput 之后设置,否则availableMetadataObjectTypes
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是一个简单的 iOS 扫描二维码实现: 1. 导入 AVFoundation 框架到你的项目中 2. 创建一个 UIView 用于显示摄像头捕获到的图像,并添加到视图中 3. 创建一个 AVCaptureSession 对象,设置采集质量和设备(摄像头),并将 AVCaptureDeviceInput 对象添加到会话中 4. 创建一个 AVCaptureMetadataOutput 对象,并将其添加到会话中,设置输出代理,并添加需要扫描的码类型 5. 创建一个 AVCaptureVideoPreviewLayer 对象,并将其添加到 UIView 上,用于显示摄像头捕获到的图像 6. 调用 AVCaptureSession 的 startRunning 方法,开始捕获摄像头数据 7. 实现 AVCaptureMetadataOutputObjectsDelegate 协议中的方法,获取扫描到的二维码信息 下面是一份示例代码,你可以根据自己的需求进行修改和完善: ``` // 创建 UIView 用于显示摄像头捕获到的图像 UIView *previewView = [[UIView alloc] initWithFrame:self.view.bounds]; [self.view addSubview:previewView]; // 创建 AVCaptureSession 对象 AVCaptureSession *session = [[AVCaptureSession alloc] init]; session.sessionPreset = AVCaptureSessionPresetHigh; // 获取设备(摄像头) AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; // 创建 AVCaptureDeviceInput 对象 NSError *error = nil; AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; if (input) { // 添加 AVCaptureDeviceInput 对象到会话中 [session addInput:input]; // 创建 AVCaptureMetadataOutput 对象 AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init]; // 添加 AVCaptureMetadataOutput 对象到会话中 [session addOutput:output]; // 设置输出代理,在主线程中执行 dispatch_queue_t mainQueue = dispatch_get_main_queue(); [output setMetadataObjectsDelegate:self queue:mainQueue]; // 添加需要扫描的码类型 NSArray *codeTypes = @[AVMetadataObjectTypeQRCode]; [output setMetadataObjectTypes:codeTypes]; // 创建 AVCaptureVideoPreviewLayer 对象 AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session]; [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; // 设置 AVCaptureVideoPreviewLayer 的 frame,并添加到 UIView 上 [previewLayer setFrame:previewView.layer.bounds]; [previewView.layer addSublayer:previewLayer]; // 开始捕获摄像头数据 [session startRunning]; } else { NSLog(@"Error: %@", error); } // 实现 AVCaptureMetadataOutputObjectsDelegate 协议中的方法,获取扫描到的二维码信息 - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { if (metadataObjects != nil && [metadataObjects count] > 0) { // 获取扫描到的二维码信息 AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0]; if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) { NSString *qrCode = [metadataObj stringValue]; NSLog(@"Scanned QR Code: %@", qrCode); } } } ``` 希望这个简单的示例能够帮助到你。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值