I have to scan GTIN-14 barcodes, also named GS1-128 or ITF-14 (http://www.gtin.info/). I've tried with AVFoundation framework adding all available barcode types but it doesn't work.
- (void)startReading
{
NSArray *barCodeTypes = #[AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeCode39Mod43Code,
AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode93Code, AVMetadataObjectTypeCode128Code,
AVMetadataObjectTypePDF417Code, AVMetadataObjectTypeQRCode, AVMetadataObjectTypeAztecCode];
NSError *error;
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if (!input) {
NSLog(#"%#", [error localizedDescription]);
}
self.captureSession = [[AVCaptureSession alloc] init];
[self.captureSession addInput:input];
AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
[self.captureSession addOutput:captureMetadataOutput];
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[captureMetadataOutput setMetadataObjectTypes:barCodeTypes];
//[captureMetadataOutput setMetadataObjectTypes:[captureMetadataOutput availableMetadataObjectTypes]];
self.videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
[self.videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[self.videoPreviewLayer setFrame:self.cameraView.layer.bounds];
[self.cameraView.layer addSublayer:self.videoPreviewLayer];
[self.captureSession startRunning];
}
It's possible with AVFoundation framework? Is there another framework to scan GTIN-14 barcodes?
Another barcode reader lib for ios is http://zbar.sourceforge.net.
Related
I am new to programming, and trying to fix this code to use the front camera instead of defaulting to the back. I'm not sure what I need to change to make this work properly.
Here is my sample code:
-(void)viewWillAppear:(BOOL)animated{
session = [[AVCaptureSession alloc] init];
[session setSessionPreset:AVCaptureSessionPresetPhoto];
AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error;
AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:&error];
if ([session canAddInput:deviceInput]) {
[session addInput:deviceInput];
}
AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
[previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
CALayer *rootLayer = [[self view] layer];
[rootLayer setMasksToBounds:YES];
CGRect frame = self.frameForCapture.frame;
[previewLayer setFrame:frame];
[rootLayer insertSublayer:previewLayer atIndex:0];
stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil];
[stillImageOutput setOutputSettings:outputSettings];
[session addOutput:stillImageOutput];
[session startRunning];
Replace this:
AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error;
AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:&error];
With this:
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
AVCaptureDevice *frontCamera;
for (AVCaptureDevice *dev in devices) {
if (dev.position == AVCaptureDevicePositionFront) {
frontCamera = dev;
break;
}
}
if (!frontCamera) {
NSLog(#"No front camera found!");
// Handle no front camera error
}
NSError *error;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:frontCamera error:&error];
I'm trying to do an AVCaptureSession on the front camera to read a PDF417 barcode, but it refuses to read the same barcodes on the front camera that it will read no problem on the back. Is there a setting I'm missing or does it have to do with the front camera appearing "mirrored?"
I tried the same thing with a QR code and it works no problem on both the front and back cameras.
_session = [[AVCaptureSession alloc] init];
NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for( AVCaptureDevice *device in videoDevices )
{
if( device.position == AVCaptureDevicePositionFront )
{
_device = device;
break;
}
}
// couldn't find one on the front, so just get the default video device.
if( ! _device)
{
_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
}
// _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
if( _device.isAutoFocusRangeRestrictionSupported )
{
if( [_device lockForConfiguration:&error] )
{
[_device setAutoFocusRangeRestriction:AVCaptureAutoFocusRangeRestrictionNear];
[_device unlockForConfiguration];
}
}
_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];
_output.metadataObjectTypes = #[AVMetadataObjectTypePDF417Code ];
_prevLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
_prevLayer.frame = self.view.bounds;
_prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self updatePreviewLayerForOrientation:[[UIApplication sharedApplication] statusBarOrientation] ];
[self.view.layer addSublayer:_prevLayer];
[_session startRunning];
I'd like to use the video preview layer on the iPhone and the iPad, but on the iPad it doesn't rotate and it has the wrong height.
Here is the code I have:
- (void)capture
{
AVCaptureSession *session = [[AVCaptureSession alloc] init];
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
error:&error];
if (!input)
{
NSLog(#"Error: %#", error);
return;
}
[session addInput:input];
//Turn on point autofocus for middle of view
[device lockForConfiguration:&error];
CGPoint point = CGPointMake(0.5,0.5);
[device setFocusPointOfInterest:point];
[device setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
[device unlockForConfiguration];
//Add the metadata output device
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[session addOutput:output];
NSLog(#"%lu",output.availableMetadataObjectTypes.count);
for (NSString *s in output.availableMetadataObjectTypes)
NSLog(#"%#",s);
//You should check here to see if the session supports these types, if they aren't support you'll get an exception
output.metadataObjectTypes = #[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeQRCode];
output.rectOfInterest = self.livevideo.bounds;
AVCaptureVideoPreviewLayer *newCaptureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
newCaptureVideoPreviewLayer.frame = self.view.layer.bounds;
newCaptureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.livevideo.layer insertSublayer:newCaptureVideoPreviewLayer above:self.livevideo.layer];
[session startRunning];
}
And:
- (void)captureFront
{
AVCaptureSession *session = [[AVCaptureSession alloc] init];
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
error:&error];
if (!input)
{
NSLog(#"Error: %#", error);
return;
}
[session addInput:input];
//Turn on point autofocus for middle of view
[device lockForConfiguration:&error];
CGPoint point = CGPointMake(0.5,0.5);
[device setFocusPointOfInterest:point];
[device setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
[device unlockForConfiguration];
//Add the metadata output device
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[session addOutput:output];
NSLog(#"%lu",output.availableMetadataObjectTypes.count);
for (NSString *s in output.availableMetadataObjectTypes)
NSLog(#"%#",s);
//You should check here to see if the session supports these types, if they aren't support you'll get an exception
output.metadataObjectTypes = #[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeQRCode];
output.rectOfInterest = self.livevideo.bounds;
AVCaptureVideoPreviewLayer *newCaptureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
newCaptureVideoPreviewLayer.frame = self.view.layer.bounds;
newCaptureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[session startRunning];
}
Image
Hi if i make a image capture screen with this
-(void)initializecam{
AVCaptureSession *session = [[AVCaptureSession alloc] init];
session.sessionPreset = AVCaptureSessionPresetMedium;
CALayer *viewLayer = self.vImagePreview.layer;
NSLog(#"viewLayer = %#", viewLayer);
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
captureVideoPreviewLayer.frame = self.vImagePreview.bounds;
[captureVideoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[self.vImagePreview.layer addSublayer:captureVideoPreviewLayer];
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!input) {
// Handle the error appropriately.
NSLog(#"ERROR: trying to open camera: %#", error);
}
[session addInput:input];
_stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil];
[_stillImageOutput setOutputSettings:outputSettings];
[session addOutput:_stillImageOutput];
[session startRunning];
}
So now i want to use zbar bar code scanning. Any one know how to do this. I searched a lot but all there is they use the image capture view and how to modify that view. All i need is that i have an image[not in camera roll] and i want to scan it by zbar no image capture view or anything. Please help. Is there is any other free library except zbar to do this??
it can be done by this
- (void)scan {
// ADD: present a barcode reader that scans from the camera feed
ZBarReaderController *reader = [ZBarReaderController new];
reader.readerDelegate = self;
ZBarImageScanner *scanner = reader.scanner;
// EXAMPLE: disable rarely used I2/5 to improve performance
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
CGImageRef imgCG = self.imgCameraView.image.CGImage;
id<NSFastEnumeration> results = [reader scanImage:imgCG];
ZBarSymbol *symbol = nil;
for(ZBarSymbol *symbolF in results){
// EXAMPLE: just grab the first barcode
symbol=symbolF;
break;
}
if([symbol.data length]>0){
NSLog(#"Bar Code ID = %#",symbol.data);
self.ticketCode=symbol.data;
[self verifybarCode];
self.vImagePreview.hidden=FALSE;
}
else
{
[[iToast makeText:AMLocalizedString(#"Image Is Not Properly Scanned\nTry Again", nil)] show];
self.vImagePreview.hidden=FALSE;
}
}
Previously i was taking ZBarReaderViewController
This is how I am setting up the camera preview in landscape mode in my iPad3
- (void)viewDidAppear:(BOOL)animated
{
AVCaptureSession *session = [[AVCaptureSession alloc] init];
session.sessionPreset = AVCaptureSessionPreset640x480;
CALayer *viewLayer = self.vImagePreview.layer;
NSLog(#"viewLayer = %#", viewLayer);
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
captureVideoPreviewLayer.frame = self.vImagePreview.bounds;
[self.vImagePreview.layer addSublayer:captureVideoPreviewLayer];
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!input) {
// Handle the error appropriately.
NSLog(#"ERROR: trying to open camera: %#", error);
}
[session addInput:input];
stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil];
[stillImageOutput setOutputSettings:outputSettings];
[session addOutput:stillImageOutput];
[session startRunning];
}
In the storyboard, I set the view to fill the entire screen, however it ends up looking like this:
And furthermore, the image is also rotated 90ยบ degrees. How can I change this, so I can make the camera preview fill the entire screen?
Thanks.
Rotate your layer:
switch (self.interfaceOrientation)
{
case UIInterfaceOrientationLandscapeRight:
[captureVideoPreviewLayer setAffineTransform:CGAffineTransformMakeRotation(-M_PI / 2)];
break;
case UIInterfaceOrientationLandscapeLeft:
[captureVideoPreviewLayer setAffineTransform:CGAffineTransformMakeRotation(M_PI / 2)];
break;
}
[self.vImagePreview.layer addSublayer:captureVideoPreviewLayer];