我正在尝试使用Apple原生API扫描Aztec代码。但我无法扫描它。在Apple指南中,我已阅读它,您可以扫描Aztec代码。但它没有用。
请检查我正在使用的代码。
#import <UIKit/UIKit.h>
@interface igViewController : UIViewController
@end
#import <AVFoundation/AVFoundation.h>
#import "igViewController.h"
@interface igViewController () <AVCaptureMetadataOutputObjectsDelegate>
{
AVCaptureSession *_session;
AVCaptureDevice *_device;
AVCaptureDeviceInput *_input;
AVCaptureMetadataOutput *_output;
AVCaptureVideoPreviewLayer *_prevLayer;
UIView *_highlightView;
UILabel *_label;
}
@end
@implementation igViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_highlightView = [[UIView alloc] init];
_highlightView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleBottomMargin;
_highlightView.layer.borderColor = [UIColor greenColor].CGColor;
_highlightView.layer.borderWidth = 3;
[self.view addSubview:_highlightView];
_label = [[UILabel alloc] init];
_label.frame = CGRectMake(0, self.view.bounds.size.height - 40, self.view.bounds.size.width, 40);
_label.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
_label.backgroundColor = [UIColor colorWithWhite:0.15 alpha:0.65];
_label.textColor = [UIColor whiteColor];
_label.textAlignment = NSTextAlignmentCenter;
_label.text = @"(none)";
[self.view addSubview:_label];
_session = [[AVCaptureSession alloc] init];
_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
_input = [AVCaptureDeviceInput deviceInputWithDevice:_device error:&error];
if (_input) {
[_session addInput:_input];
} else {
NSLog(@"Error: %@", error);
}
_output = [[AVCaptureMetadataOutput alloc] init];
[_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[_session addOutput:_output];
_output.metadataObjectTypes = [_output availableMetadataObjectTypes];
for (NSString* avail in _output.metadataObjectTypes) {
NSLog(@"Avail...%@", avail);
}
_prevLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
_prevLayer.frame = self.view.bounds;
_prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer:_prevLayer];
[_session startRunning];
[self.view bringSubviewToFront:_highlightView];
[self.view bringSubviewToFront:_label];
}
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
NSLog(@"Failed...");
CGRect highlightViewRect = CGRectZero;
AVMetadataMachineReadableCodeObject *barCodeObject;
NSString *detectionString = nil;
NSArray *barCodeTypes = @[AVMetadataObjectTypeAztecCode];
for (AVMetadataObject *metadata in metadataObjects) {
NSLog(@".....%@", metadata.type);
for (NSString *type in barCodeTypes) {
if ([metadata.type isEqualToString:type])
{
barCodeObject = (AVMetadataMachineReadableCodeObject *)[_prevLayer transformedMetadataObjectForMetadataObjectAVMetadataMachineReadableCodeObject *)metadata];
highlightViewRect = barCodeObject.bounds;
detectionString = [(AVMetadataMachineReadableCodeObject *)metadata stringValue];
break;
}
}
if (detectionString != nil)
{
_label.text = detectionString;
break;
}
else
_label.text = @"(none)";
}
//_label.text = @"(nonessss)";
_highlightView.frame = highlightViewRect;
}
@end
答案 0 :(得分:3)
这是我在SO上的第一个答案,我是Objective-C和iOS开发的初学者,所以请跟我一点温柔。
我无法帮助您修复代码中的错误,因为作为初学者,我仍然很难看到正在发生的事情,但我想告诉您仅仅几天之前我成功地跟踪了this tutorial关于如何做到你需要的东西。我调整了教程代码并在需要的地方添加了注释,因此如果您想尝试,应该很容易理解。因为似乎不赞成只在这里发布一个链接,所以我发布了我的代码。
这是ViewController
直接打开扫描视图,如果找到条形码(在我的情况下为aztec),则会做出反应。应该很容易适应您的需求。在教程中,他们使用AVMetadataObjectTypeQRCode
,但要扫描Aztec代码,只需替换AVMetadataObjectTypeAztecCode
即可。我已经在我的代码中完成了这项工作。
ScanVC.h(在您的情况下为igViewController
)
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@interface ScanVC : UIViewController <AVCaptureMetadataOutputObjectsDelegate>
@property (retain, nonatomic) UILabel *scannerWindow;
@property (retain, nonatomic) UILabel *statusLabel;
@property (retain, nonatomic) UIButton *cancelButton;
@end
<强> ScanVC.m 强>
#import "ScanVC.h"
@interface ScanVC ()
@property (nonatomic) BOOL isReading;
@property (nonatomic, strong) AVCaptureSession *captureSession;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer;
@end
@implementation ScanVC
@synthesize cancelButton;
@synthesize statusLabel;
@synthesize scannerWindow;
- (void)viewDidLoad {
[super viewDidLoad];
_isReading = NO;
_captureSession = nil;
//place a close button
cancelButton = [UIButton buttonWithType:UIButtonTypeSystem];
[cancelButton addTarget:self action:@selector(closeScan) forControlEvents:UIControlEventTouchUpInside];
[cancelButton setTitle:@"Close" forState:UIControlStateNormal];
cancelButton.frame = CGRectMake(0, 410, 250, 40);
[self.view addSubview:cancelButton];
//place a status label
statusLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 340, 250, 40)];
statusLabel.text = @"Currently not scanning";
[self.view addSubview:statusLabel];
//place the scanner window (adjust the size)
scannerWindow = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 250, 250)];
scannerWindow.text = @"Camera Capture Window";
[self.view addSubview:scannerWindow];
//start the scan immediately when the view loads
[self startStopScan];
}
- (void)closeScan {
if(_isReading) {
[self stopReading];
}
_isReading = !_isReading;
//dismiss the view controller here?
}];
}
- (void)startStopScan {
if (!_isReading) {
if([self startReading]) {
[statusLabel setText:@"Scanning for Barcode"];
}
} else {
[self stopReading];
}
_isReading = !_isReading;
}
- (BOOL)startReading {
NSError *error;
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if(!input) {
NSLog(@"%@", [error localizedDescription]);
return NO;
}
_captureSession = [[AVCaptureSession alloc] init];
[_captureSession addInput:input];
AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
[_captureSession addOutput:captureMetadataOutput];
dispatch_queue_t dispatchQueue;
dispatchQueue = dispatch_queue_create("myQueue", NULL);
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
[captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeAztecCode]];
//show the preview to the user
_videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
[_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[_videoPreviewLayer setFrame:scannerWindow.layer.bounds];
[scannerWindow.layer addSublayer:_videoPreviewLayer];
[_captureSession startRunning];
return YES;
}
-(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:AVMetadataObjectTypeAztecCode]) {
[statusLabel performSelectorOnMainThread:@selector(setText:) withObject:[metadataObj stringValue] waitUntilDone:NO];
[self performSelectorOnMainThread:@selector(stopReading) withObject:nil waitUntilDone:NO];
_isReading = NO;
//do things after a successful scan here
NSLog(@"scanner output %@", [metadataObj stringValue]);
}
}
}
- (void)stopReading {
[_captureSession stopRunning];
_captureSession = nil;
[_videoPreviewLayer removeFromSuperlayer];
}
@end