Optimise camera for QR codes - iphone

I have a AVCaptureDevice specifically to scan QR codes (using AVMetadataObjectTypeQRCode). My goal is to make QR code scanning as fast as possible.
Several settings of the AVCaptureDevice camera (e.g. focus and exposure) can be programmatically adjusted in iOS.
What camera optimisations I can make to minimise the time it takes to capture a QR code on an iPhone?

Most of those settings optimal values vary based on the environment (eg dark/bright room, near/far QR Code etc.), so unless you know your user's environment (eg if the app was used exclusively in factory assembly lines), the default is probably best.
However (according to this source), If you know that the QR code will be near the camera you can speed up autofocus by setting autoFocusRangeRestriction to a near range value. You could also make sure that smoothAutoFocusEnabled is set to false.

I was used AVCaptureDevice.
This code working find i was used this in my bar code app.try this code.
-(void)BarcodeStart
{
_highlightView = [[UIView alloc] init];
_highlightView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleBottomMargin;
_highlightView.layer.borderColor = [UIColor lightGrayColor].CGColor;
_highlightView.layer.borderWidth = 3;
[barcameraView 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];
//BackBtn UP side Show
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
//[button addTarget:self action:#selector(aMethod:)forControlEvents:UIControlEventTouchDown];
UIImageView *img = [[UIImageView alloc] init];
button.frame = CGRectMake(3,19,30,30);
img.image = [UIImage imageNamed:#"backBtnImg.png"];
[button setImage:img.image forState:UIControlStateNormal];
[_highlightView addSubview:button];
//
_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];
_prevLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
// _prevLayer.frame = CGRectMake(20, 70, 280, 280);
_prevLayer.frame = barcameraView.bounds;
_prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[barcameraView.layer addSublayer:_prevLayer];
[_session startRunning];
[barcameraView bringSubviewToFront:_highlightView];
[self.view bringSubviewToFront:_label];
}

Related

UIImagePickerController does not show edit screen

I'm playing around with a cameraOverLayView and encountered a weird behavior. Before presenting the UIImagePickerController, I set allowsEditing to YES. After the capture screen comes up, I tap on a button that triggers takePicture(). Instead of presenting the editing screen, the delegate method didFinishPickingMediaWithInfo() gets called right away. Can anyone help me figure out what I could be doing wrong? I pasted some of my code below...
Thanks!
- (BOOL)shouldStartCameraController {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == NO) {
return NO;
}
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
float overlayOffset = 0;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
if (screenSize.height > 480.0f) {
overlayOffset = 195;
} else {
overlayOffset = 103;
}
} else {
/*Do iPad stuff here.*/
}
UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]
&& [[UIImagePickerController availableMediaTypesForSourceType:
UIImagePickerControllerSourceTypeCamera] containsObject:(NSString *)kUTTypeImage]) {
cameraUI.mediaTypes = [NSArray arrayWithObject:(NSString *) kUTTypeImage];
cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
if ([UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceRear]) {
cameraUI.cameraDevice = UIImagePickerControllerCameraDeviceRear;
} else if ([UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceFront]) {
cameraUI.cameraDevice = UIImagePickerControllerCameraDeviceFront;
}
} else {
return NO;
}
UIView *cameraOverlayView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, cameraUI.view.frame.size.width, cameraUI.view.frame.size.height)];
UIImageView *cameraOverlayImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"iphone5_camera_overlay.png"]];
cameraOverlayImageView.frame = CGRectMake(0, 0, cameraUI.view.frame.size.width, cameraUI.view.frame.size.height);
[cameraOverlayView addSubview:cameraOverlayImageView];
UILabel *cameraLabel = [[UILabel alloc] initWithFrame:CGRectMake( 0.0f, self.view.bounds.size.height-overlayOffset, self.view.bounds.size.width, 50.0f)];
[cameraLabel setTextAlignment:NSTextAlignmentCenter];
[cameraLabel setBackgroundColor:[UIColor clearColor]];
[cameraLabel setTextColor:[UIColor whiteColor]];
[cameraLabel setShadowColor:[UIColor colorWithWhite:0.0f alpha:0.300f]];
[cameraLabel setShadowOffset:CGSizeMake( 0.0f, -1.0f)];
[cameraLabel setFont:[UIFont boldSystemFontOfSize:18.0f]];
[cameraOverlayView addSubview:cameraLabel];
UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
[cancelButton addTarget:self action:#selector(cancelButtonPressed:) forControlEvents:UIControlEventTouchDown];
[cancelButton setFrame:CGRectMake(10, cameraOverlayView.frame.size.height-60, 50, 50)];
[cancelButton setBackgroundColor:[[UIColor whiteColor] colorWithAlphaComponent:0.5f]];
[cameraOverlayView addSubview:cancelButton];
UIButton *snapButton = [UIButton buttonWithType:UIButtonTypeCustom];
[snapButton addTarget:self action:#selector(takePictureButtonPressed:) forControlEvents:UIControlEventTouchDown];
[snapButton setFrame:CGRectMake(110, cameraOverlayView.frame.size.height-60, 100, 50)];
[snapButton setBackgroundColor:[[UIColor whiteColor] colorWithAlphaComponent:0.5f]];
[cameraOverlayView addSubview:snapButton];
cameraUI.allowsEditing = YES;
cameraUI.showsCameraControls = NO;
cameraUI.delegate = self;
self.imagePickerController = cameraUI;
[self presentModalViewController:cameraUI animated:YES];
return YES;
}
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer {
[self shouldPresentPhotoCaptureController];
}
#pragma mark - UIBarButton Selectors
- (void)takePictureButtonPressed:(id)sender {
NSLog(#"takePictureButtonPressed...");
// TODO: take picture!
[self.imagePickerController takePicture];
}
Possible dublicate: How do I use [camera takePhoto] and edit using UIImagePicker - UIImagePickerController.allowsEditing = YES
According to takePicture: method in Apple documentation:
Use this method in conjunction with a custom overlay view to initiate the programmatic capture of a still image. This supports taking more than one picture without leaving the interface, but requires that you hide the default image picker controls.
Calling this method while an image is being captured has no effect. You must wait until the associated delegate object receives an imagePickerController:didFinishPickingMediaWithInfo: message before you can capture another picture.
It seems that this approach (custom overlay) it is configured in order to be managed by yourself. Even if "allowsEditing = YES" the taken picture will be directly sent to imagePickerController:didFinishPickingMediaWithInfo:.
Based on that if we want to edit the taken picture using our custom user interface we should create an according custom edit screen for that purpose.

How do I save a photo with a label overlaid on the photo?

So I have data I want to overlay on a photo when it is taken. Here is my code. Is there an easier way to overlay data on photos?
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *cameraImage = [info objectForKey:UIImagePickerControllerOriginalImage];
UIImageView *imageViewToSave = [[UIImageView alloc] initWithImage:cameraImage];
CGRect textFrame = CGRectMake(0, 0, imageViewToSave.frame.size.width-20, 325);
UILabel *tempLabel = [[UILabel alloc] initWithFrame:textFrame];
tempLabel.text = self.temperatureText.text;
tempLabel.font = self.imageLabelFont;
tempLabel.adjustsFontSizeToFitWidth = YES;
tempLabel.textAlignment = NSTextAlignmentRight;
tempLabel.textColor = self.tempGreen;
tempLabel.backgroundColor = [UIColor clearColor];
[imageViewToSave addSubview:tempLabel];
UIGraphicsBeginImageContext(imageViewToSave.bounds.size);
[imageViewToSave.layer renderInContext:UIGraphicsGetCurrentContext()];
cameraImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self.library saveImage:cameraImage toAlbum:#"Node Therma" withCompletionBlock:^(NSError *error)
{
if (error!=nil)
{
NSLog(#"Big error: %#", [error description]);
}
}];
}
Just tested this, and it works ...
- (UIImage *)imageWithBackground:(UIImage *)background text:(NSString *)text textColor:(UIColor *)textColor {
UIImageView *imageView = [[UIImageView alloc] initWithImage:background];
UIView *composition = [[UIView alloc] initWithFrame:imageView.bounds];
[composition addSubview:imageView];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(/* where you want the label */)];
label.text = text;
label.backgroundColor = [UIColor clearColor];
label.textColor = textColor;
[composition addSubview:label];
UIGraphicsBeginImageContext(composition.bounds.size);
[composition.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *composedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return composedImage;
}
Your code seems ok, compared to mine which works fine, but try using a new local variable
when getting the screenshot, like this:
UIImage *cameraImage2 = UIGraphicsGetImageFromCurrentImageContext();
then save cameraImage2.
Also make sure that self.tempGreen is not ClearColor.

setting rectangular border for UIButton

I have to implement a button with rectangular border and it should be like this
and I am using the following code to do that:
-(void)createDynamicView:(CGRect)frame{
UIButton *drugimgBtn = [UIButton buttonWithType:UIButtonTypeCustom];
drugimgBtn.frame = frame;//CGRectMake(0, 0, 155, 130);
NSString *myurl = responseDrugInfo.ThumbImg; //by rajesh
NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:myurl]];
UIImage *tbImage = [[UIImage alloc] initWithData:imageData];
[drugimgBtn setBackgroundImage:tbImage forState:UIControlStateNormal];
[drugimgBtn addTarget:self action:#selector(imageButtonAction:) forControlEvents:UIControlEventTouchUpInside];
UIView * prescView = [[UIView alloc]init];
prescView.frame = frame;
prescView.layer.borderColor = [UIColor lightGrayColor].CGColor;
prescView.layer.borderWidth = 1.0f;
[prescView addSubview:drugimgBtn];
[scrollview addSubview:drugimgBtn];
//[prescView release];
[myurl release];
[tbImage release];
}
The output is as follow:
How do I implement a rectangular border so it can appeared like the same in the first image?

UIImage imageWithData

I have a UITable and when I click on a row I load a set of images.
I create the images with
UIImage *image = [UIImage imageWithData:data];
The problem is that ever time I click on the same row, the images are re-allocated into memory, like if no cache it is used and no memory is freed, so the allocated memory keep increasing. (I see this using the Inspector on both the device and the emulator)
I am releasing everything and also, with clang, everything looks fine.
The point is that after a while my app crashes.
Any suggestion or idea?
EDIT:
Here is the portion of code I think is generating the issue:
UIView *main = [[[UIView alloc] initWithFrame:rectScrollView] autorelease];
for (int i=0; i<[contentArray count]; i++) {
float targetWidth = rectScrollView.size.width;
float targetHeight = rectScrollView.size.height;
Link *tmp_link = [contentArray objectAtIndex:i];
AsyncImageView* asyncImage = nil;
if(tmp_link!=nil){
CGRect imageFrame = CGRectMake(targetWidth*i, 0, targetWidth, targetHeight);
//asyncImage = [[[AsyncImageView alloc] initWithFrame:imageFrame ] autorelease];
asyncImage = [[AsyncImageView alloc] initWithFrame:imageFrame ];
asyncImage.contentMode = UIViewContentModeScaleAspectFit;
NSURL* url = [NSURL URLWithString:[[IMG_SERVER_URL stringByAppendingString: tmp_link.url] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
[asyncImage loadImageFromURL:url];
[self.scrollView addSubview:(UIImageView *)asyncImage];
[asyncImage release];
}
if ([tmp_link.caption length] > 0 && asyncImage!=nil) {
float marginTop = 25;
UILabel *caption = [[UILabel alloc] init];
caption.text = tmp_link.caption;
caption.textAlignment = UITextAlignmentCenter;
caption.textColor = [UIColor whiteColor];
caption.font = [UIFont systemFontOfSize:12];
caption.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.4];
CGRect captionFrame = CGRectMake((i * targetWidth), marginTop+10, targetWidth, 20.0f);
caption.frame = captionFrame;
[self.scrollView addSubview:caption];
[caption release];
}
//[asyncImage release];
}
[main addSubview:scrollView];
[scrollView release];
if (pageControlEnabledTop) {
rectPageControl = CGRectMake(0, 5, scrollWidth, 15);
}
else if (pageControlEnabledBottom) {
//rectPageControl = CGRectMake(0, (scrollHeight - 25), scrollWidth, 15);
rectPageControl = CGRectMake(0, (scrollHeight), scrollWidth, 15);
}
if (pageControlEnabledTop || pageControlEnabledBottom) {
//pageControl = [[[UIPageControl alloc] initWithFrame:rectPageControl] autorelease];
pageControl = [[UIPageControl alloc] initWithFrame:rectPageControl];
pageControl.numberOfPages = [contentArray count];
pageControl.currentPage = page;
[main addSubview:pageControl];
[pageControl release];
}
if (pageControlEnabledTop || pageControlEnabledBottom || rememberPosition) self.scrollView.delegate = self;
//if (margin) [margin release];
return (UIScrollView *)main;
And it is used like this:
reviewImagesImage = [[IGUIScrollViewImage alloc] init];
if([currentReview.linkScreenshots count]>0){
//reviewImages
reviewImages = [[UIView alloc] init];
//placing the images
CGRect frameImages = reviewImages.frame;
frameImages.origin.x = 10;
frameImages.origin.y = (infoView.frame.origin.y + infoView.frame.size.height + 10.0f);
frameImages.size.width = 300;
frameImages.size.height = 350.0f;
reviewImages.frame = frameImages;
reviewImages.backgroundColor = [UIColor clearColor];
[reviewImagesImage setContentArray:currentReview.linkScreenshots];
[reviewImagesImage setWidth:reviewImages.frame.size.width andHeight: reviewImages.frame.size.height];
[reviewImagesImage enablePageControlOnBottom];
[reviewImagesImage setBackGroudColor: [UIColor clearColor]];
UIScrollView *tmp_sv = [reviewImagesImage getWithPosition:0];
[reviewImages addSubview:tmp_sv];
[self.view addSubview:reviewImages];
[reviewImages release];
}
I have noticed that if I try to release reviewImagesImage my app crashes :/
Of course no cache is used because new UIImage will be created from the data every time. If memory usage significantly increased like you have said, it is most likely that it is our fault that unintentionally keep the reference retained somewhere.
Once you've set your image with imageWithData, save the image to the filepath in the app bundle.

Parsing text file into NSArray but how do I extract it?

I have this code
NSArray *wordListArray = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#”sowpods” ofType:#”txt”]
encoding:NSMacOSRomanStringEncoding error:NULL] componentsSeparatedByString:#”\n”]];
My question is how can I extract this text and update a label in a Scrollview? I just need the user to be able to scroll down and read whats in the text file...
Sounds like what you want to do is something like:
CGRect appFrame = [[[UIApplication sharedApplication] keyWindow]frame];
UIScrollView* scrollView = [[[UIScrollView alloc] initWithFrame:appFrame] autorelease];
CGRect lblFrame = CGRectMake(0.0f, 0.0f, scrollView.frame.size.width, 20.0f);
for (NSString* word in wordListArray)
{
UILabel* lbl = [[[UILabel alloc] initWithFrame:lblFrame]autorelease];
lbl.text = word;
[scrollView addSubview:lbl];
lblFrame.origin.y += 20.0f;
}
scrollView.contentSize = CGSizeMake(lblFrame.size.width, lblFrame.origin.y);
[mainView addSubview:scrollView]; // mainView = up to you
(NB: I haven't tested this, could contain errors, but just want to give you ideas to work with.)