I am using ZBar iPhone SDK in one of my projects (iOS SDK 5.1 ,XCode 4.4.1 and device running iOS 5.5.1). I am using the embedded scanner from the examples provided in the SDk itself.
Now the issue which I am facing is that I successfully scan a bar code and move to another view controller ( using navigation controller). When I come back (pop the second view controller) the scanner i.e the ZBarReaderView doesn't scan the subsequent bar codes , infact the overlay shows a blur image of the scanned barcode and is never able to scan it properly.
This is what all I have implemented . In BarScannerViewController.h I have declared
ZBarReaderView* readerView;
with property
#property (nonatomic , retain) IBOutlet UIImageView* imgvScannedBarCode;
Now this is connected to one of the views in xib.
Finally I use set up the required methods as follows -
- (void)viewDidLoad {
[super viewDidLoad];
// the delegate receives decode results
readerView.readerDelegate = self;
[readerView start];
}
- (void) viewDidAppear: (BOOL) animated {
// run the reader when the view is visible
[activityIndicatorScanning startAnimating];
[readerView start];
}
- (void) viewWillDisappear: (BOOL) animated {
[activityIndicatorScanning stopAnimating];
[readerView stop];
}
With all this set up when I scan any bar code say EAN123 for the first time I get the call back in
- (void) readerView: (ZBarReaderView*) view
didReadSymbols: (ZBarSymbolSet*) syms
fromImage: (UIImage*) img
{
// do something useful with results
ZBarSymbol *symbol = nil;
for(symbol in syms) {
barCodeFound = YES;
break;
}
// EXAMPLE: do something useful with the barcode data
NSLog(#"%#",symbol.data);
}
but on subsequent runs (After I push a view and come back on this screen again) I get blurred view.
Am I missing something here ? Any help/Suggestion/Comments would be helpful.
Here's the code that I use to start (and endlessly restart) the scanner. Interestingly, I note that I never stop the scan, but it works very reliably.
- (void) startScan
{
ZBarReaderViewController *reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
ZBarImageScanner *scanner = reader.scanner;
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
// present and release the controller
[self presentViewController:reader animated:YES completion:nil]; // Modal
[reader release];
}
I could solve the Blur issue by reconfiguring the SDK in my project. I followed the embedded scanner example as provided on ZBarSDk. I guess I might have missed some essential settings while configuring it earlier.
Related
We are using Zbar bar code reader from last 2 years. With iOS 7 and Xcode 5, after scanning 5 bar codes the app is reaching 100 % cpu use for iOS 7 device(I can see that in Xcode debug mode) and app become less responsive. We never had issue in earlier iOS versions, everything worked fine.
Is thing changed in iOS 7 related to camera launching and ZBar SDK is not updated? Is anyone else facing same issue with iOS 7?
Solved doing this:
in the viewdidload
readerqr = [ZBarReaderViewController new];
readerqr.readerDelegate = self;
readerqr.showsHelpOnFail = NO;
ZBarImageScanner *scanner = readerqr.scanner;
[scanner setSymbology: 0
config: ZBAR_CFG_ENABLE
to: 0];
[scanner setSymbology: ZBAR_QRCODE
config: ZBAR_CFG_ENABLE
to: 1];
// you can use this to support the simulator
if(TARGET_IPHONE_SIMULATOR) {
cameraSim = [[ZBarCameraSimulator alloc]
initWithViewController: self];
cameraSim.readerView = readerView;
}
create ZBarReaderViewController *readerqr; as a property of your viewcontroller.
to use it:
-(void) showqr:(id)sender
{
[self presentViewController:readerqr animated:YES completion:nil];
return;
}
This way works, no leak, no cpu 100%
After seeing the same issue,
I moved from
ZBarReaderViewController
to
ZBarReaderView
The disappointing part of this, though, is if you are using features like Overlay in the ZBarReaderViewController, you have to recode how that all works and you have to implement things like starting and stopping the scanner, manually.
But essentially, you need something like this in your IBAction:
ZBarReaderView *reader = [ZBarReaderView new];
[self.view addSubview:reader];
reader.readerDelegate = self;
reader.tracksSymbols=YES;
ZBarImageScanner *scanner = reader.scanner;
reader.tag = 99999999;
// the important part here is to START the scanning
[reader start];
Also, remember to change your delegate in your header to ZBarReaderViewDelegate
Also, the delegate "method" that gets called, at least in my code, is now (versus the imagePickerController)
-(void) readerView: (ZBarReaderView*) view
didReadSymbols: (ZBarSymbolSet*) syms
fromImage: (UIImage*) img
{
for(ZBarSymbol *sym in syms) {
[view stop];
[self closeCameraScanner];
// I am also setting reader to NIL but I don't really know if this is necessary or not.
reader=nil;
}
}
-(void)closeCameraScanner{
UIView * v = [self.view viewWithTag:99999999];
if (nil != v) {
[v removeFromSuperview];
}
[self.view endEditing:YES];
}
So, that's a quick and dirty way to do this. I have some additional code for manually creating the overlay and for limiting the scan crop but as far as simply getting it running, this did the trick for me.
I solved the problem that Barry Mc G had.
I had the same issues even after patched zBar SDK with iOS7 from http://nerdvision.net/app-development/ios/zbar-sdk.
( 5th - 6th time opening the page it freezes at 100% CPU.)
Whether you subclass ZBarViewController or use it directly, you present the view controller and dismiss it later when you're done with the scanner. I found the reason why this happens and the reason was I didn't stop the video streaming. In ZBarReaderView, there's a function - (void)stop; and if you run this function after you are done with the scanner, you won't see the problem ( 5th - 6th time opening the page it freezes at 100% CPU.). At least in my case it worked and hope it works for you as well.
i fixed the issue now with implementing the Diff from the source.
If someone of you need it, you can download the compiled zBar SDK with iOS7 Support here.
You can just replace the libzbar.a - this should work. But i uploaded the complete SDK as someone may need it too with headers etc.
http://nerdvision.net/app-development/ios/zbar-sdk
I was same issue and easily fixed.
Do not remember about below code.
You must put this code when out of reader view.
[readerview stop];
cpu over load issue was cause by duplicated camera stream.
had same Problems, Scanner seems to be freeze ..
I fixed it like joaquin ...
Make a Property for the reader and when you call it multiple times you can check, if a Object of the reader where initialize ...
Here is what i´m doing:
- (IBAction)ShowZBarReader
{
// ADD: present a barcode reader that scans from the camera feed
if (!self.reader) {
self.reader = [[ZBarReaderViewController alloc]init];
}
self.reader.readerDelegate = self;
self.reader.supportedOrientationsMask = ZBarOrientationMaskAll;
ZBarImageScanner *scanner = self.reader.scanner;
// zusätliche Configurationen ...
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
// stellt Bild zur verfügung
[self presentViewController:self.reader animated:YES completion:nil];
}
Worked perfectly for me ! Hope it helps :)
I've implemented the camera inside of my app with the default showsCameraControls = YES, and the issue I am having is when the user confirms that the image is a keeper, it dismisses the camera with [self.delegate didFinishWithCamera]. I would like to remain in the Camera view until the user is done taking photos. Without [self.delegate didFinishWithCamera], the app hangs after the user confirms they want to keep the photo and never returns back to the live camera feed. How do I remain in the camera view? Your help is appreciated!
#implementation PHFPhotoOverlayVC
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.imagePickerController = [[UIImagePickerController alloc] init];
self.imagePickerController.delegate = self;
}
return self;
}
- (void)setupImagePicker:(UIImagePickerControllerSourceType)sourceType
{
self.imagePickerController.sourceType = sourceType;
if (sourceType == UIImagePickerControllerSourceTypeCamera)
{
self.imagePickerController.mediaTypes =
[NSArray arrayWithObjects:(NSString *) kUTTypeImage, nil];
self.imagePickerController.showsCameraControls = YES;
#if false
if ([[self.imagePickerController.cameraOverlayView subviews] count] == 0)
{
CGRect overlayViewFrame = self.imagePickerController.cameraOverlayView.frame;
CGRect newFrame = CGRectMake(0.0,
CGRectGetHeight(overlayViewFrame) -
self.view.frame.size.height - 10.0,
CGRectGetWidth(overlayViewFrame),
self.view.frame.size.height + 10.0);
self.view.frame = newFrame;
[self.imagePickerController.cameraOverlayView addSubview:self.view];
}
#endif
}
}
#pragma mark -
#pragma mark UIImagePickerControllerDelegate
- (void) imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
self.imagePickerController.mediaTypes =
[NSArray arrayWithObjects:(NSString *) kUTTypeImage, nil];
self.imagePickerController.showsCameraControls = YES;
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
if (self.delegate)
[self.delegate didTakePicture:image];
[self.delegate didFinishWithCamera];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self.delegate didFinishWithCamera];
}
#end
In order to achieve this, you will have to implement your own method for taking a picture, since this default button causes the view to dismiss itself.
Obviously, you can do this by setting showsCameraControls=NO, but then you'd have to recreate all the other functionality that you still want.
I've never done this, but it should be possible to leave showsCameraControls=YES and use the cameraOverlayView to simply layer an identical "Take Picture" button over the existing one. If you do that, you just need to have that button call the method -takePicture from the instance of your UIImagePickerViewController.
Hopefully that's enough, feel free to comment and ask for any clarification.
You're going to need to implement a custom camera - check out Apple's SquareCam example
You'll be using AVFoundation and will be able to implement any kind of custom behavior when a photo is taken (including just staying on that camera page) - you'll even have to save it to the Photo Library yourself (the SquareCam example shows you how to do this). This also means that if you need the crop/resize controls, you'll have to create them yourself, as well as a picker view (grid gallery view) if you want the user to be able to review their photos after taking them.
It's probably around intermediate level stuff - took me a few days to implement, but if your app is in any way focused on photos, this is definitely the way to go. Gives you complete control of the camera UI and behavior.
Oh, and yeah you'll have to implement the flash button, shutter button, shutter effect, tap to focus, and anything else yourself too. AVFoundation basically gives you a straight pipe to the camera lens (figuratively).
I have an application in which I have a UIView (Zbarsdk reader view) in my xib. When a button is tapped, that view should be loaded. But actually when the button is tapped, the previous view is loading at first (from which I came to my view). But after running once then again running then the correct view is loading? (From login I came to home. In home I have one button to load one view that is separate in my xib, but when running first it is loading the login screen again. But without deleting that build when u run again that code in simulator is loading that correct view). Does anybody know why?
- (IBAction) tappressed
{
// ADD: present a barcode reader that scans from the camera feed
ZBarReaderViewController *reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
[reader willRotateToInterfaceOrientation:UIInterfaceOrientationPortrait duration:0];
//[self.readerView willRotateToInterfaceOrientation:orient duration:0];
//reader.supportedOrientationsMask = ZBarOrientationMask(UIInterfaceOrientationLandscapeRight);
// [reader shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationLandscapeRight];
//reader.supportedOrientationsMask = ZBarOrientationMask(UIInterfaceOrientationLandscapeLeft);
reader.sourceType=UIImagePickerControllerSourceTypeCamera;
// UIImageView *overlayImage=[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"overlaygraphic.png"]];
//overlayImage.bounds=CGRectMake(50, 75, 320-100, 480-150);
reader.cameraOverlayView=cameraOverlay;
ZBarImageScanner *scanner = reader.scanner;
// TODO: (optional) additional reader configuration here
// EXAMPLE: disable rarely used I2/5 to improve performance
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
// present and release the controller
[self presentModalViewController:reader animated:YES];
// [self.view addSubview:reader.view];
[reader release];
}
i've got a ZBarReaderView created from storyboard with 216x20 px which is shown as roughly 230x50 px because ZBarReaderView doesn't take it's size too serious...
It all works very well, however it behaves really strange when I call start on that readerView. It starts the cam but then in maybe half a second the readerView zooms a bit and the camera picture inside the readerView moves down and then up again.
It's not terrible but it look kinda bad. Anyone got any ideas what might be causing this and how to solve it? Maybe the sdk has some sort of hidden callback for the readiness of the scanner, i could hide it until the scanner says it's ready and then show the scanner like .5 seconds later...
barcodeReader is the iboutlet to the ZBarReaderView and scannerLoading is an iboutlet to a uiactivityindicatorview which is animating until the scanner is loaded.
These are the only settings which are changed from default, except the frame which is set in the storyboard of course.
[barcodeReader setReaderDelegate:self];
[barcodeReader setAllowsPinchZoom:false];
[barcodeReader start];
/* this works because [barcodeReader start] blocks ui updates until the scanner
is running, i know it's not a good solution but since there doesn't seem to
be a callback or delegate method like scannerDidStart or something it seems
to be the only way... */
[scannerLoading stopAnimating];
Thanks for your help!
I just posted an answer to a retaliated question:
ZBarReadview with custom size from StoryBoard,but when it's called,it's size is not I set
Maybe the answer also solves your problem.
In short:
When using Interface Builder or Storyboard to create a view and assign the ZBarReaderView to it, you have to check "Clip Subviews" in the properties for the camera image to keep the size of the view.
Just add another view to make it as cameraoverlayview with an image view having the image which is having required part of it as transparent.then in the button action `
// ADD: present a barcode reader that scans from the camera feed
ZBarReaderViewController *reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
reader.supportedOrientationsMask = ZBarOrientationMaskAll;
reader.sourceType=UIImagePickerControllerSourceTypeCamera;
//reader.cameraDevice = UIImagePickerControllerCameraDeviceFront;
reader.cameraOverlayView=cameraOverlay;
if( [UIImagePickerController isCameraDeviceAvailable: UIImagePickerControllerCameraDeviceFront ])
{
reader.cameraDevice = UIImagePickerControllerCameraDeviceFront;
}
ZBarImageScanner *scanner = reader.scanner;
reader.wantsFullScreenLayout = YES;
// TODO: (optional) additional reader configuration here
// EXAMPLE: disable rarely used I2/5 to improve performance
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
reader.showsZBarControls = NO;
// present and release the controller
[self presentModalViewController:reader animated:YES];
//[appdel.navigationController pushViewController:reader animated:YES];
//[reader.view addSubview:collect];
[reader release];add this and then also add
`- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
// ADD: get the decode results
id results =
[info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
// EXAMPLE: just grab the first barcode
break;
[self rewards:symbol.data];
}
`
as a method .hope this will solve your issue
The code to set image to imageView is:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
SDWebImageManager *manager = [SDWebImageManager sharedManager];
UIImage *cachedImage = [manager imageWithURL:_url];
if (cachedImage)
{
_imageView.image = cachedImage;
[spinner stopAnimating];
}
else
{
[spinner startAnimating];
[manager downloadWithURL:_url delegate:self];
}
// Configure the view for the selected state
[super setSelected:selected animated:animated];
}
- (void)webImageManager:(SDWebImageManager *)imageManager
didFinishWithImage:(UIImage *)_image
{
[spinner stopAnimating];
_imageView.image = _image;
[self setNeedsLayout];
}
I use SDWebImage
this works every time in simulator, but when I run the app in the device (Ipod touch)
80 % of the images is just black, but if I go to another view and back the images are set (from cache).
I have try to set delay on _imageView = _image, but change.
(Answered in a question edit. Converted to a community wiki answer. See Question with no answers, but issue solved in the comments (or extended in chat) )
The OP wrote:
Now I have try the code on a Iphone 3gs and it works perfect, can understand why it wont work on ipod touch.
When i Compiled and Run as "Release" it works on ipod, but not in as debugger. Wierd..