iPhone Camera Overlay App With Custom Button Example

Note: Since iOS 4 there is a better way to do this which I have documented in a new post here.

There seems to be a lot of interest recently in making apps that use a camera view with an overlay for augmented reality or what some might call pseudo-augmented reality applications (because often these apps just layer an image or data on a camera view). I wasn’t satisfied with the few examples I found on the topic so I decided to try one myself. I will endeavour to make it as clear as I can and show you how to make a custom button while I am at it, but I do assume a basic knowledge of Objective-C and iPhone app development in Xcode.

Screenshot 2009.12.10 18.46.38 200x300 iPhone Camera Overlay App With Custom Button Example

OverlayViewTester screenshot

So first I will describe the OverlayViewTester app. Basically it just overlays some cool looking red selection braces on a camera view and has a button that when pressed performs a ‘scan’ for two seconds and lets you know by adding a “Scanning…” label at the top of the screen during that time. So really it does nothing, but it looks good and is a good first step to making a more fun and interesting interactive camera overlay app.

To get started, download the source code. Next I will go through the files in the project and present the juicy bits. Consult the source code you downloaded for the full meal deal.

OverlayViewTesterApDelegate

Taking a look at the project we start with a typical app delegate, OverlayViewTesterAppDelegate which loads the OverlayViewController. Nothing monumental there so I won’t bother reproducing it here.

OverlayViewController

Now on to the OverlayViewController where we create the camera view.

In the interface, OverlayViewController.h: we define some constants:

// Transform values for full screen support:
#define CAMERA_TRANSFORM_X 1
//#define CAMERA_TRANSFORM_Y 1.12412 //use this is for iOS 3.x
#define CAMERA_TRANSFORM_Y 1.24299 // use this is for iOS 4.x

// iPhone screen dimensions:
#define SCREEN_WIDTH  320
#define SCREEN_HEIGTH 480

In the implementation, OverlayViewController.m there is a bit of a GOTCHA. The line

[self presentModalViewController:picker animated:YES];

must be called in viewDidAppear: not in a viewDidLoad: method. Here it is:

- (void) viewDidAppear:(BOOL)animated {
    OverlayView *overlay = [[OverlayView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGTH)];

    // Create a new image picker instance:
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];

    // Set the image picker source:
    picker.sourceType = UIImagePickerControllerSourceTypeCamera;

    // Hide the controls:
    picker.showsCameraControls = NO;
    picker.navigationBarHidden = YES;

    // Make camera view full screen:
    picker.wantsFullScreenLayout = YES;
    picker.cameraViewTransform = CGAffineTransformScale(picker.cameraViewTransform, CAMERA_TRANSFORM_X, CAMERA_TRANSFORM_Y);

    // Insert the overlay:
    picker.cameraOverlayView = overlay;

    // Show the picker:
    [self presentModalViewController:picker animated:YES];
    [picker release];

    [super viewDidAppear:YES];
}

I think the comments make it clear what is going on there.

OverlayView

Next lets look at the custom subclass of UIView called OverlayView. This is where we actually create our overlay.

In the interface, OverlayView.h we declare two new methods:

- (void)scanButtonTouchUpInside;
- (void)clearLabel:(UILabel *)label;

Here are the important parts of the implementation, OverlayView.m:

- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        // Clear the background of the overlay:
	self.opaque = NO;
	self.backgroundColor = [UIColor clearColor];

	// Load the image to show in the overlay:
	UIImage *overlayGraphic = [UIImage imageNamed:@"overlaygraphic.png"];
	UIImageView *overlayGraphicView = [[UIImageView alloc] initWithImage:overlayGraphic];
	overlayGraphicView.frame = CGRectMake(30, 100, 260, 200);
	[self addSubview:overlayGraphicView];
	[overlayGraphicView release];

	ScanButton *scanButton = [[ScanButton alloc] initWithFrame:CGRectMake(130, 320, 60, 30)];

	// Add a target action for the button:
	[scanButton addTarget:self action:@selector(scanButtonTouchUpInside) forControlEvents:UIControlEventTouchUpInside];
	[self addSubview:scanButton];
    }
    return self;
}

- (void) scanButtonTouchUpInside {
    UILabel *scanningLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 50, 120, 30)];
    scanningLabel.backgroundColor = [UIColor clearColor];
    scanningLabel.font = [UIFont fontWithName:@"Courier" size: 18.0];
    scanningLabel.textColor = [UIColor redColor];
    scanningLabel.text = @"Scanning...";

    [self addSubview:scanningLabel];

    [self performSelector:@selector(clearLabel:) withObject:scanningLabel afterDelay:2];

    [scanningLabel release];
}

- (void)clearLabel:(UILabel *)label {
    label.text = @"";
}

Notice that we have used an instance of ScanButton which we will get to next. When the ScanButton detects a UIControlEventTouchUpInside it calls the scanButtonTouchUpInside method which places a label on the screen for 2 seconds.

ScanButton

So finally we are left with our ScanButton. You might think that for a custom button we would subclass UIButton, but unless you really want to use the UIBUtton method setTitle:ForState it is recommended that you subclass UIControl. It will save you a world of hurt.

Here is the interface, ScanButton.h:

#import <Foundation/Foundation.h>

@interface ScanButton : UIControl {
}

- (void)buttonPressed;

@end

I put the buttonPressed method in here for future use. It is meant to be used to change things related to the button itself and not the actions associated with the button in the OverlayViewController. You could for example use it to have the button’s image or state or both toggle.

Last but not least we have the implementation, ScanButton.m:

#import "ScanButton.h"

@implementation ScanButton

- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
	// Set button image:
	UIImageView *buttonImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 60, 30)];
	buttonImage.image = [UIImage imageNamed:@"scanbutton.png"];

	[self addTarget:self action:@selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside]; // for future use

        [self addSubview:buttonImage];
    }
    return self;
}

- (void)buttonPressed {
    // TODO: Could toggle a button state and/or image
}

@end

So there you have it. A custom camera overlay and a custom button. I hope that with this code you will be well on your way to writing much more useful, interesting and creative apps than this example. Happy coding!

In case you missed it here is the source code link again.

Note: If you didn’t see this message at the top of the post, since iOS 4 there is a better way to do this which I have documented in a new post here.

Share and Enjoy:
  • printfriendly iPhone Camera Overlay App With Custom Button Example
  • digg iPhone Camera Overlay App With Custom Button Example
  • stumbleupon iPhone Camera Overlay App With Custom Button Example
  • delicious iPhone Camera Overlay App With Custom Button Example
  • facebook iPhone Camera Overlay App With Custom Button Example
  • yahoobuzz iPhone Camera Overlay App With Custom Button Example
  • twitter iPhone Camera Overlay App With Custom Button Example
  • googlebookmark iPhone Camera Overlay App With Custom Button Example
  • reddit iPhone Camera Overlay App With Custom Button Example

About jjob

I'm a technologist and a music producer. I make sound, write code and build things with electronics and microcontrollers.
This entry was posted in app, AR, code, iOS, iPhone, XCode and tagged , . Bookmark the permalink.

57 Responses to iPhone Camera Overlay App With Custom Button Example

  1. Thanks for sharing the code and taking the time to write this up!

    • jjob says:

      You’re welcome, glad it was helpful!

      • ambu says:

        hey friend

        good job

        i want to show the camera when the user will click take pic button
        but that camera view will be specific part of view not full screen camera how can i do this please help???

        • jjob says:

          You should be able to make the preview whatever size you want. I recommend playing around with the demo and trying different sizes for the preview layer.

  2. Hey, great help with the code.. Just what I needed to get my head around camera overlays.

    The source code seems to have gone down though on that link, any chance of a re-upload?

    Thanks Alex

    • jjob says:

      Thanks Alexander! The repo is back up on GitHub.

      • Thanks for putting the link back up!

        Im having a little bit of trouble implementing this within a tab bar application.. Is there any possibility you could write a quick how-to from turning this from a stand alone app into something that could be dropped into a tab bar app?

        Thanks Alex

  3. jchaike says:

    Where is the source code for this project?

    • jjob says:

      It is at https://github.com/jj0b/OverlayViewTester which is linked in the post, but not very obviously. I will make it a little more accessible in the post. :-)

      • jchaike says:

        oh i got it.
        this seems cool, but when i run it (xcode 4) on OverlayView.m, under initWithFrame, the line: if (self = [super initWithFrame:frame]) { gives a warning:
        Semantic Issue: Using the result of an assignment as a condition without parentheses

        thanks for posting the source code to this. it might be exactly what i was looking for

        • jjob says:

          I’ll update the project. Xcode 4 likes you to use parenthesis so that it is: if ((self = [super initWithFrame:frame])) {….

  4. Dev says:

    Thanks for the code, it worked well. Any of you have tried to do camera overlay ? (like to detect a particular object using a iphone camera and linking to backend server for object detection. I am trying to do this but i am stuck.

    • jjob says:

      Not sure about detecting a specific object, but there is a good demo from WWDC last year that shows how to detect specific colours. I think it was called FindMyiCone.

      • Dev says:

        WWDC? What is that? Sorry , cause i am kinda new to iPhone Apps Development. There is a demo? hmm … thats would be help just changing the colour into objects will allow the program to work

        • jjob says:

          Google is your friend. WWDC is the Apple Worldwide Developer Conference where Apple shows of their software technology to developers every year. If you are an iOS developer you should have access to the videos and source code from WWDC 2010 at https://developer.apple.com/videos/wwdc/2010/.As I recall the FindMyiCone demo app shows the latest way to get live input from the camera and how to detect a specified color range.

  5. Bill Brasky says:

    Very helpful. Although I noticed there is about a 20px blank area below the camera view. Did you notice the same? If so, how did you fix it?

    • jjob says:

      Hi Bill,

      I hadn’t noticed that before but when I loaded the app sure enough the black bar was there. I verified that the frame is being set right, so I determined that the transform vertical scale factor must be the issue. A quick Google search revealed this StackOverflow post that says the scale factors need to be different on iOS4 (I originally wrote this app for iOS3). From that post they say the magic number for iOS3 is 1.12412 and for iOS4 is 1.24299.

      The post shows how these are derived but there is no explanation of where the numbers are coming from. For iOS3 it says: “1536/320=4.8 2048/4.8=427 480-427=53 53/427=0.121412 +1=1.12412″ and for iOS4 it says “1936/320= 6.05 2592/6.05=428 480-428=52 52/(428/2)=0.24299 +1=1.24299″ I’m sure Google would be your friend if you really wanted to know.

      I’ll update the post and the GitHub repository. Thanks for letting me know about this!

  6. Kofi says:

    Thanks for the tutorial jjob. I had a quick question about the camera overlay. Is it possible to use the camera overlay with AVCapture instead of UIImagePicker? If so, do you know how to implement it?

    • jjob says:

      Yes, it is absolutely possible to do this using the AVFoundation framework. I would even suggest that since iOS 4 this has been the best way to do it. I have meant to do an updated sample app for a while showing how to do this using the AVCapture stuff. I will try to get a sample up this week.

      In the meantime take a look at the AVFoundation documentation and at the WWDC 2010 session video 409: Using the Camera with AV Foundation. There is some great sample code from WWDC as well.

  7. Pingback: iOS Camera Overlay Example Using AVCaptureSession | musicalgeometry

  8. Carles says:

    Hi,

    I see in the image you have the “iPhone Advanced Projects” book. Is it good? Which references do you recommend?

    Thanks for the code, really helpful.

    • jjob says:

      There are a lot of great programming books out there. Is there something in particular you want to learn? I by no means have the definitive collection but I do have a small collection of iOS books and could possibly recommend something if you let me know what you are interested in.

      • Carles says:

        Hi! I’m interested in image processing. I want to develop apps using the camera and making some image processing.
        Thanks!

        • jjob says:

          I don’t have any books that cover image processing but I would recommend you start by reading the Quartz 2D Programming Guide in the Apple docs. There are also some useful sample apps in the WWDC sessions that you can access from your developer account.

  9. Phillip says:

    I just want to say Thank You! very much for putting your code out in the wild.

    I have been searching for days for some guidance in turning the iPhone camera into a reading glass. I am not certain that your code will actually serve my purpose, but it is superior to what I have found, which in truth, has not been much.

    My goal is not to develop a(nother) magnifying glass app, but to add it as a tab bar feature to my unfinished gratuity estimator app. My next goal is to learn how to turn on the LED’s to illuminate menu reading in dimly lit eateries.

    Hopefully, I will be able to add an ‘action’ to the tab bar item to spring straight into the reading glass feature and improve the UI experience.

    I sincerely appreciate your generosity in releasing your code.

  10. Luke says:

    Hey, Little Q.

    I have used this code to put an overlay on screen for people to align their face to when taking a photo.. I have put code in place that checks that availability of front and rear cameras..

    I would like to enable people who have both cameras the ability to switch between the two, however, when using the overlay it does not allow me to use the built in camera switch button.

    is there a way of doing this manually and very simply? can i use a custom IBAction to achieve this? thanks, Luke.

  11. Arun says:

    Hello..nice tutorial…

    Can you kindly help me to rotate the overlay view according to the orientation ?

  12. Pingback: Introduction to Augmented Reality on the iPhone | Ray Wenderlich

  13. Arthur says:

    Hey friend.

    Great tutorial.

    I’ve been trying to save image when the scan button is pressed, but still i have no solution to do that. Any sugestions?

  14. Pingback: iPhone上面的现实增强(Augmented Reality )入门教程 | cocoadev

  15. Savvas_6 says:

    Hello
    congratulations about your post! it’s very useful.
    i would like to ask you if its possible to make the overlay buttons and labels on the user interface, instead of code.

    • jjob says:

      I don’t see why not. You should be able to make whatever you want in IB and add it to your view. Just make sure that the stuff in IB has a transparent background.

  16. Savvas_6 says:

    i also want to create a button to zoom each time you press it.(normal zoom – 2X – Full zoom)
    can you please provide the code for that button?

  17. aadil says:

    sir your code is not working on stimulator 4.3, what is the problem i am not understanding
    can u pls help…..
    is OverlayViewController is a controller like viewController

  18. Pingback: iPhone Camera Overlay App With Custom Button Example | gan凌雲

  19. Will Kortum says:

    Hey, how would I enable the button to save a picture? I saw your other tutorial, but I found that this version will let you resize the view area as on the other one I couldn’t resize the live view area of the camera. Do you have any tips on resizing the live view area on the newer tutorial or saving an image in this tutorial?

    • jjob says:

      You can resize and reposition the preview with the following two methods that you will find in viewDidLoad in AROverlayViewController:

      [[[self captureManager] previewLayer] setBounds:layerRect];
      [[[self captureManager] previewLayer] setPosition:CGPointMake(CGRectGetMidX(layerRect),CGRectGetMidY(layerRect))];

      The first one sets the size of the preview layer and the second sets the position by specifying the centre point.

      • Will Kortum says:

        Thanks for the quick response, but in this code where would i put the numbers (x and y coordinates) for positioning, or the numbers for the size of the aroverlayviewcontroller?

        • jjob says:

          On iOS a CGRect defines a rectangle. You can make a CGRect with the c function CGRectMake(x,y,width,height). You can actually just embed that as the argument in the setBounds: method. So you would have:

          [[[self captureManager] previewLayer] setBounds:CGRectMake(0,0,320,480)]; // this would make the preview fill the screen

          On iOS a CGPoint defines a point. You can make a CGPoint with the c function CGPointMake(x,y). Again, you can just put this inline as the argument to the setPosition: method.

          [[[self captureManager] previewLayer] setPosition:CGPointMake(160,240)]; // this would centre the preview on the screen

          Of course you can adjust those coordinates and sizes to be whatever you like.

  20. Pingback: Loading an external view controller, from a button click on another view controller

  21. Nick says:

    Hi, thanks for this and the updated code, hard to find good examples of this! :) I’m pretty new at this and wonder.. do you have another version with more (steps) commented explanation? Would make it easier to understand what’s going on :)

    One other question though.. I’m doing this with storyboards and I’m trying to get an in interface builder created design (toolbar with buttons on bottom, navbar with text on top, transparent for the rest) to act as overlay. I can’t seem to get this to work. What should change for this? I’m not sure what controller and elements the view should be made of, and how to connect it into the code for the overlay.

    Thanks!

  22. Felipe Butcher says:

    Thank you man!! I was looking for this!

    When recording videos, do you know how to add something like a label on the video? I mean after the video is saved, the label will appear when it’s played…

    Thanks again! great post :)

  23. Pingback: take picture method on cameraOverlayView (SOLVED) | PHP Developer Resource

  24. Chandra says:

    Thanks for the code.It was very well..I am new to iOS programming and if i try to run this on the device it is returning error about the certificate.Do i need valid certificate inorder to run it?

    • jjob says:

      You need an iOS developer account and you need to create certificates and provisioning profiles to run apps from Xcode. If you have those then make sure that the project and target are using the correct provisioning profiles you want to use.

  25. Thavasi durai says:

    Hi thanks for the code its really nice, I want to take photo with overlay view and need to save it in photo album to do this what are changes i need to do. i tried but once i tap the capture button overlay view is upside down (around 40px) and also i could save it in photo album but in photo album overlay view is not displaying? please help me asap. i raised this question in stack overflow also

  26. amir says:

    hi if any method provide to ios when a camera is open it’s on 5x zooming mode…

    Thanks..

  27. ajt says:

    Hey Thanks for the fantastic example. Everything works great except there’s a view before the camera view appears. any simple way to start with the camera view directly? thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>