【问题标题】:Wrong result on Barcode scanning using AVFoundation framework使用 AVFoundation 框架进行条码扫描的错误结果
【发布时间】:2014-05-30 07:26:49
【问题描述】:

我正在使用 iOS 7 AVFoundation 框架进行条码扫描。它对我来说很好,但在某些条码上它给了我错误的结果。

我正在添加代码文件和条形码来生成问题。请看一下并帮助我找出问题所在。

代码示例:

ViewController.h 类-

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface ViewController : UIViewController <AVCaptureMetadataOutputObjectsDelegate>
{
    AVCaptureSession                *_session;
    AVCaptureDevice                 *_device;
    AVCaptureDeviceInput            *_input;
    AVCaptureMetadataOutput         *_output;
    AVCaptureVideoPreviewLayer      *_prevLayer;

    UIView                          *_highlightView;

    IBOutlet    UIView              *_viewBg;
    IBOutlet    UIButton            *_btnScanning;
}

@end

ViewController.m 类方法 -

- (void)setScanningVideoOrientation
{
    if ([UIDevice currentDevice].orientation == UIInterfaceOrientationPortrait)
    {
        _prevLayer.connection.videoOrientation = AVCaptureVideoOrientationPortrait;
    }
    else if ([UIDevice currentDevice].orientation == UIInterfaceOrientationPortraitUpsideDown)
    {
        _prevLayer.connection.videoOrientation = AVCaptureVideoOrientationPortraitUpsideDown;
    }
    else if ([UIDevice currentDevice].orientation == UIInterfaceOrientationLandscapeLeft)
    {
        _prevLayer.connection.videoOrientation = AVCaptureVideoOrientationLandscapeLeft;
    }
    else if ([UIDevice currentDevice].orientation == UIInterfaceOrientationLandscapeRight)
    {
        _prevLayer.connection.videoOrientation = AVCaptureVideoOrientationLandscapeRight;
    }
}


- (void)startScanning
{
    // Create Session.------------------------------------------------------
    _session = nil;
    _session = [[AVCaptureSession alloc] init];
    _device = nil;
    _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error = nil;

    _input = nil;
    _input = [AVCaptureDeviceInput deviceInputWithDevice:_device error:&error];
    if (_input)
    {
        [_session addInput:_input];

        _output = nil;
        _output = [[AVCaptureMetadataOutput alloc] init];
        [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
        [_session addOutput:_output];

        _output.metadataObjectTypes = [_output availableMetadataObjectTypes];

        _prevLayer = nil;
        _prevLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
        _prevLayer.frame = _viewBg.frame;
        _prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
        [self setScanningVideoOrientation];
        [self.view.layer addSublayer:_prevLayer];

        [_session startRunning];
    } else
    {
        NSLog(@"Error: %@", error);
    }
    //----------------------------------------------------------------------
}

在这个委托方法中。我得到错误的条形码字符串。请看一下“detectionString”。

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray     *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
    CGRect highlightViewRect = CGRectZero;
    AVMetadataMachineReadableCodeObject *barCodeObject;
    NSString *detectionString = nil;
    NSArray *barCodeTypes = @[AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeCode39Code,     AVMetadataObjectTypeCode39Mod43Code,
                          AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode93Code, AVMetadataObjectTypeCode128Code,
                          AVMetadataObjectTypePDF417Code, AVMetadataObjectTypeQRCode, AVMetadataObjectTypeAztecCode];

    for (AVMetadataObject *metadata in metadataObjects) {
        for (NSString *type in barCodeTypes) {
            if ([metadata.type isEqualToString:type])
            {
                barCodeObject = (AVMetadataMachineReadableCodeObject *)[_prevLayer     transformedMetadataObjectForMetadataObject:(AVMetadataMachineReadableCodeObject *)metadata];
                highlightViewRect = barCodeObject.bounds;
                detectionString = [(AVMetadataMachineReadableCodeObject *)metadata stringValue];
                break;
            }
        }

        if (detectionString != nil)
        {
            NSLog(@"ViewController-->captureOutput-->detectionString = %@",detectionString);
            [self stopScanning];
            break;
        }
    }

    barCodeObject   = nil;
    detectionString = nil;
    barCodeTypes    = nil;
}

条码图片 -

我得到结果 - 0649954006029

但应该是 - 649954006029。

至于其他一些条形码,我在实际条形码扫描字符串之前看到“l”。

希望它能帮助您找出问题。

谢谢。

【问题讨论】:

  • 不要将代码作为图像添加到您的问题中。请将相关代码复制并粘贴为文本并正确格式化。它使阅读更容易,并且更容易在答案中引用。
  • 希望它能帮助您找出问题所在。如果附加的图像不适合扫描,请使用您附近物品的条形码。你肯定会得到这个问题。谢谢!
  • 你能去掉前导零吗?
  • @Shane.. 感谢您的评论,但这不是实际的解决方案。我需要知道这背后的原因,但我仍然遇到这个问题。 AVFoundation 为某些条码提供了正确的结果,因此去除前导字符不是正确的解决方案。
  • AFAIK 这是因为代码是 12 个符号而不是 13 个,所以它有前导零。

标签: ios ios7 avfoundation barcode barcode-scanner


【解决方案1】:

您获得 13 位代码的原因是您尝试扫描 UPC-A 代码 (649954..),而 iOS 没有单独的 UPC-A 代码类别。

UPC-A 代码作为 EAN13 代码被扫描进来,它们有 13 位长,所以它们的前缀是 0。

来自AVFoundation/AVMetadata.h

/*! @constant AVMetadataObjectTypeEAN13Code

@abstract 实例的标识符 具有类型的 AVMetadataMachineReadableCodeObject AVMetadataObjectTypeEAN13代码。

@讨论 从 EAN-13(包括 UPC-A)代码生成的 AVMetadataMachineReadableCodeObject 对象返回此常量作为它们的类型。 */

AVF_EXPORT NSString *const AVMetadataObjectTypeEAN13Code NS_AVAILABLE(NA, 7_0);

【讨论】:

  • 感谢 Sandeep 的准确回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-16
  • 1970-01-01
  • 2021-04-05
  • 2012-07-17
  • 2014-11-04
  • 1970-01-01
  • 2018-01-22
相关资源
最近更新 更多