One of the great feature of AVFoundation framework is the ability of discover and read bar Codes in real time.
Here i am mainly going to interact (discover and read ) with QR code.
QR(Quick Response) code is a type of matrix barcode or two dimensional barcode uses four standardized encoding mode (numeric, alphanumeric, byte/binary and kanji) to store data (like URLs, Text, Numbers). For more details Click here
For more details about AVFoundation Framework Click here.
Create a new Project
import AVFoundation Framework.
Now go to main storyboard and add a view(Subclass of UIView), a label and a button.
A view will be display what camera is recording in the form of image.
Label is used for display resultant string data after scanning QRcode (or the data store in QR code).
And button is for start and stop scanning.
Now go to ViewController.h file and declare properties.
@property (nonatomic, weak) IBOutlet UIView *previewView;
@property (weak, nonatomic) IBOutlet UILabel *statusLabel;
@property (weak, nonatomic) IBOutlet UIButton *scanButton;
also declare two more properties
@property (nonatomic, strong) AVCaptureSession *captureSession;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer;
Back to main storyboard and connect outlets.
Switch to ViewController.m file and add following code inside viewDidLoad method
//set button corner radious and border color
self.scanButton.layer.borderColor = [UIColor lightGrayColor].CGColor;
self.scanButton.layer.borderWidth = 0.7;
self.scanButton.layer.cornerRadius = 3;
self.scanButton.clipsToBounds = YES;
//setting lable color and border
self.statusLabel.layer.borderColor = [UIColor lightGrayColor].CGColor;
self.statusLabel.layer.borderWidth = 0.7;
self.statusLabel.layer.cornerRadius = 2;
self.statusLabel.clipsToBounds = YES;
In the above code we are just adding border color and corner radius on label and button.
Add new method with the name startReading()
-(Void) startReading{
NSError *error;
//1. Define capture device
//For Front Camera
// AVCaptureDevice *captureDevice = [AVCaptureDevice deviceWithUniqueID:@"com.apple.avfoundation.avcapturedevice.built-in_video:1"];
//For Default Camera
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//2.Define Capture Device
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if (!input) {
NSLog(@"Error = %@", error.localizedDescription);
NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
[[[UIAlertView alloc] initWithTitle:@"Camera Unavailable" message:[NSString stringWithFormat:@"The %@ has not been given a permission to your camera. Please check the Privacy Settings: Settings -> %@ -> Privacy -> Camera", appName, appName] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil] show];
return NO;
}
//3.Initialize session
self.captureSession = [[AVCaptureSession alloc] init];
[self.captureSession addInput:input]; //add input device to session
//4.Set metadata output
AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
[self.captureSession addOutput:captureMetadataOutput];// Add output data to session
//5. set delegate
dispatch_queue_t dispatchQueue;
dispatchQueue = dispatch_queue_create("myQueue", NULL);
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue]; //set delegate
//6.set the type of metadata objects to process
[captureMetadataOutput setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
//7.Add video preview layer
self.videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
[self.videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
self.videoPreviewLayer.frame = self.previewView.bounds;
[self.previewView.layer addSublayer:self.videoPreviewLayer];
//8.Start session
[self.captureSession startRunning];
}
1.Capture Device:
An AVCaptureDevice represents a physical device that provides realtime input media data, such as video and audio. A input device can be the camera or microphone.
2.Capture Device Input:
AVCaptureDeviceInput is a concrete subclass of AVCaptureInput that provides an interface for capturing media from an AVCaptureDevice.
3. Capture Session:
AVCaptureSession is the central hub of the AVFoundation capture classes.To perform a real-time capture, a client may instantiate AVCaptureSession and add appropriate.
4. Capture Metadata Output
AVCaptureMetadataOutput is a concrete subclass of AVCaptureOutput that can be used to process metadata objects from an attached connection. Instances of AVCaptureMetadataOutput emit arrays of AVMetadataObject instances such as detected faces, barcodes.
5.SetDelegate
Sets the receiver's delegate that will accept metadata objects and dispatch queue on which the delegate will be called. A serial dispatch queue must be used to guarantee that metadata objects will be delivered in order.
6. Set metadataObjectTypes:
Specifies the types of metadata objects that the receiver.
7.Preview:
AVCaptureVideoPreviewLayer quickly render the raw data collected by the camera on the screen, means we can also say, AVCaptureVideoPreviewLayer is display a preview of what the camera is capturing.
AVCaptureVideoPreviewLayer is a subclass of CALayer that we add as a sublayer of preview view's layer.
8.Start the session
startRunning to start the flow of data from inputs device to outputs data.
Now add delegate method for receive output data.
-(void) captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
if (metadataObjects != nil && [metadataObjects count]>0) {
id metadataObj= [metadataObjects objectAtIndex:0];
if ([metadataObj isKindOfClass:[AVMetadataMachineReadableCodeObject class]]) {
AVMetadataMachineReadableCodeObject *barCodeObject;
barCodeObject = (AVMetadataMachineReadableCodeObject *)[self.videoPreviewLayer transformedMetadataObjectForMetadataObject:(AVMetadataMachineReadableCodeObject *)metadataObj];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"metadata readable object count = %d \n Meta Data = %@",(int)metadataObjects.count,metadataObjects);
self.statusLabel.hidden = NO;
[self.statusLabel performSelectorOnMainThread:@selector(setText:) withObject:[metadataObj stringValue] waitUntilDone:NO];
[self stopReading];
[self.scanButton setTitle:@"Scan" forState:UIControlStateNormal];
self.scanButton.enabled = YES;
});
}
}
}
add another method for stop reading
-(void) stopReading{
[self.captureSession stopRunning];
self.captureSession = nil;
}
Now we have enough code for reading a QRcode, we just need to digger our code.
Add one more method for start and stop reading with user interaction.
Declare a IBAction method in ViewController.h file
-(IBAction)buttonAction:(id)sender
Go to ViewController.h file and define IBAction method
-(IBAction)buttonAction:(id)sender{
if ([self.captureSession isRunning] == YES) {
self.statusLabel.hidden = YES;
self.statusLabel.text = @"";
[self stopReading];
[self.scanButton setTitle:@"Scan" forState:UIControlStateNormal];
}
else{
if ([self startReading]) {
self.statusLabel.hidden = NO;
self.statusLabel.text = @"Scanning...";
[self startReading];
[self.scanButton setTitle:@"Stop" forState:UIControlStateNormal];
}
}
}
Now go to main storyboard file and connect IBAction method to button click event.
Now run the App and scan a QR code, you can see the encoded data in QR code on label.
Click here for complete project.
Here i am mainly going to interact (discover and read ) with QR code.
QR(Quick Response) code is a type of matrix barcode or two dimensional barcode uses four standardized encoding mode (numeric, alphanumeric, byte/binary and kanji) to store data (like URLs, Text, Numbers). For more details Click here
For more details about AVFoundation Framework Click here.
Create a new Project
import AVFoundation Framework.
Now go to main storyboard and add a view(Subclass of UIView), a label and a button.
A view will be display what camera is recording in the form of image.
Label is used for display resultant string data after scanning QRcode (or the data store in QR code).
And button is for start and stop scanning.
Now go to ViewController.h file and declare properties.
@property (nonatomic, weak) IBOutlet UIView *previewView;
@property (weak, nonatomic) IBOutlet UILabel *statusLabel;
@property (weak, nonatomic) IBOutlet UIButton *scanButton;
also declare two more properties
@property (nonatomic, strong) AVCaptureSession *captureSession;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer;
Back to main storyboard and connect outlets.
Switch to ViewController.m file and add following code inside viewDidLoad method
//set button corner radious and border color
self.scanButton.layer.borderColor = [UIColor lightGrayColor].CGColor;
self.scanButton.layer.borderWidth = 0.7;
self.scanButton.layer.cornerRadius = 3;
self.scanButton.clipsToBounds = YES;
//setting lable color and border
self.statusLabel.layer.borderColor = [UIColor lightGrayColor].CGColor;
self.statusLabel.layer.borderWidth = 0.7;
self.statusLabel.layer.cornerRadius = 2;
self.statusLabel.clipsToBounds = YES;
In the above code we are just adding border color and corner radius on label and button.
Add new method with the name startReading()
-(Void) startReading{
NSError *error;
//1. Define capture device
//For Front Camera
// AVCaptureDevice *captureDevice = [AVCaptureDevice deviceWithUniqueID:@"com.apple.avfoundation.avcapturedevice.built-in_video:1"];
//For Default Camera
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//2.Define Capture Device
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if (!input) {
NSLog(@"Error = %@", error.localizedDescription);
NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
[[[UIAlertView alloc] initWithTitle:@"Camera Unavailable" message:[NSString stringWithFormat:@"The %@ has not been given a permission to your camera. Please check the Privacy Settings: Settings -> %@ -> Privacy -> Camera", appName, appName] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil] show];
return NO;
}
//3.Initialize session
self.captureSession = [[AVCaptureSession alloc] init];
[self.captureSession addInput:input]; //add input device to session
//4.Set metadata output
AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
[self.captureSession addOutput:captureMetadataOutput];// Add output data to session
//5. set delegate
dispatch_queue_t dispatchQueue;
dispatchQueue = dispatch_queue_create("myQueue", NULL);
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue]; //set delegate
//6.set the type of metadata objects to process
[captureMetadataOutput setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
//7.Add video preview layer
self.videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
[self.videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
self.videoPreviewLayer.frame = self.previewView.bounds;
[self.previewView.layer addSublayer:self.videoPreviewLayer];
//8.Start session
[self.captureSession startRunning];
}
1.Capture Device:
An AVCaptureDevice represents a physical device that provides realtime input media data, such as video and audio. A input device can be the camera or microphone.
2.Capture Device Input:
AVCaptureDeviceInput is a concrete subclass of AVCaptureInput that provides an interface for capturing media from an AVCaptureDevice.
3. Capture Session:
AVCaptureSession is the central hub of the AVFoundation capture classes.To perform a real-time capture, a client may instantiate AVCaptureSession and add appropriate.
4. Capture Metadata Output
AVCaptureMetadataOutput is a concrete subclass of AVCaptureOutput that can be used to process metadata objects from an attached connection. Instances of AVCaptureMetadataOutput emit arrays of AVMetadataObject instances such as detected faces, barcodes.
5.SetDelegate
Sets the receiver's delegate that will accept metadata objects and dispatch queue on which the delegate will be called. A serial dispatch queue must be used to guarantee that metadata objects will be delivered in order.
6. Set metadataObjectTypes:
Specifies the types of metadata objects that the receiver.
7.Preview:
AVCaptureVideoPreviewLayer quickly render the raw data collected by the camera on the screen, means we can also say, AVCaptureVideoPreviewLayer is display a preview of what the camera is capturing.
AVCaptureVideoPreviewLayer is a subclass of CALayer that we add as a sublayer of preview view's layer.
8.Start the session
startRunning to start the flow of data from inputs device to outputs data.
Now add delegate method for receive output data.
-(void) captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
if (metadataObjects != nil && [metadataObjects count]>0) {
id metadataObj= [metadataObjects objectAtIndex:0];
if ([metadataObj isKindOfClass:[AVMetadataMachineReadableCodeObject class]]) {
AVMetadataMachineReadableCodeObject *barCodeObject;
barCodeObject = (AVMetadataMachineReadableCodeObject *)[self.videoPreviewLayer transformedMetadataObjectForMetadataObject:(AVMetadataMachineReadableCodeObject *)metadataObj];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"metadata readable object count = %d \n Meta Data = %@",(int)metadataObjects.count,metadataObjects);
self.statusLabel.hidden = NO;
[self.statusLabel performSelectorOnMainThread:@selector(setText:) withObject:[metadataObj stringValue] waitUntilDone:NO];
[self stopReading];
[self.scanButton setTitle:@"Scan" forState:UIControlStateNormal];
self.scanButton.enabled = YES;
});
}
}
}
add another method for stop reading
-(void) stopReading{
[self.captureSession stopRunning];
self.captureSession = nil;
}
Now we have enough code for reading a QRcode, we just need to digger our code.
Add one more method for start and stop reading with user interaction.
Declare a IBAction method in ViewController.h file
-(IBAction)buttonAction:(id)sender
Go to ViewController.h file and define IBAction method
-(IBAction)buttonAction:(id)sender{
if ([self.captureSession isRunning] == YES) {
self.statusLabel.hidden = YES;
self.statusLabel.text = @"";
[self stopReading];
[self.scanButton setTitle:@"Scan" forState:UIControlStateNormal];
}
else{
if ([self startReading]) {
self.statusLabel.hidden = NO;
self.statusLabel.text = @"Scanning...";
[self startReading];
[self.scanButton setTitle:@"Stop" forState:UIControlStateNormal];
}
}
}
Now go to main storyboard file and connect IBAction method to button click event.
Now run the App and scan a QR code, you can see the encoded data in QR code on label.
Click here for complete project.
No comments:
Post a Comment