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

本文介绍了如何使用AVFoundation框架在iOS中实现二维码和条形码的扫描功能,包括设置摄像头、限制扫描范围、创建扫描线动画、手动调整焦距以及从相册扫描二维码的步骤。通过设置rectOfInterest来限制扫描区域,并利用AVCaptureDevice的属性调整焦距。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

最近需要做一个二维码扫描功能,在网上找了很多资料,有两个比较有名气的第三方框架: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为空,程序会出现以下崩溃信息:“[AVCaptureMetadataOutput setMetadataObjectTypes:] - unsupported type found. Use -availableMetadataObjectTypes.”

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值