1

我有一个单视图应用程序,我正在尝试根据这个解释测试 iOS7 的 AVCaptureMetadataOutput。我的 ViewController 符合AVCaptureMetadataOutputObjectsDelegate并且代码看起来像这样(几乎和 Mattt 的完全一样):

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    // Testing the VIN Scanner before I make it part of the library
    NSLog(@"Setting up the vin scanner");
    AVCaptureSession *session = [[AVCaptureSession alloc] init];
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error = nil;

    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
                                                                        error:&error];
    if (input) {
        [session addInput:input];
    } else {
        NSLog(@"Error: %@", error);
    }

    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    [session addOutput:output];

    [session startRunning];
}
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputMetadataObjects:(NSArray *)metadataObjects
       fromConnection:(AVCaptureConnection *)connection
{
    NSString *code = nil;
    for (AVMetadataObject *metadata in metadataObjects) {
        if ([metadata.type isEqualToString:AVMetadataObjectTypeCode39Code]) {
            code = [(AVMetadataMachineReadableCodeObject *)metadata stringValue];
            break;
        }
    }

    NSLog(@"code: %@", code);
}

当我在 iOS7 设备上运行它时(我尝试过 iPhone 4 和 iPhone 4s)XCode 记录“设置 vin 扫描仪”但相机(即 AVCaptureSession)永远不会打开。

编辑1:

我添加了以下代码以在屏幕上显示相机输出:

AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:session];

// Display full screen    
previewLayer.frame = self.view.frame;

// Add the video preview layer to the view
[self.view.layer addSublayer:previewLayer];

但是显示很奇怪,不符合屏幕,旋转的方式也没有意义。另一个问题是,当我将相机聚焦在条形码上时,元数据委托方法永远不会被调用。请看下面的图片:

肖像屏幕截图 风景截图

4

1 回答 1

7

相机不会像 UIImagePickerController 那样打开。问题是您的代码对输出没有任何作用。您需要添加一个预览层来显示相机在流入时的输出。

AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:session];

// Display full screen    
previewLayer.frame = CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height);

// Add the video preview layer to the view
[self.view.layer addSublayer:previewLayer];

[session startRunning];

编辑**
在深入查看您的代码后,我发现了更多问题。

首先,您还需要设置要搜索的 MetaDataObjectTypes,现在您不需要寻找任何有效的对象类型。这应该在您将输出添加到会话之后添加。您可以在文档中查看可用类型的完整列表

[output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code]];

其次,您的 AVCaptureSession *session 是 viewDidLoad 中的局部变量,将其放在您的 @interface ViewController () 之后,如下所示。

@interface ViewController ()
@property (nonatomic, strong) AVCaptureSession *session;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.session = [[AVCaptureSession alloc] init];

    // Testing the VIN Scanner before I make it part of the library
    NSLog(@"Setting up the vin scanner");
    self.session = [[AVCaptureSession alloc] init];
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error = nil;

    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
                                                                    error:&error];
    if (input) {
        [self.session addInput:input];
    } else {
        NSLog(@"Error: %@", error);
    }

    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    [self.session addOutput:output];

    [output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code]];

    [self.session startRunning];
}
于 2013-09-25T17:22:40.520 回答