Image Controller

Ratings:
(4)
Views: 779
Banner-Img
Share this blog:

Using the Camera-UIImagePickerController

Rather than working directly with an iPhone’s camera, you use the UIImagePickerController to manipulate an iPhone’s camera and photo library. Using the UIImagePickerController, you take, or select, a photo, optionally edit the photo, and then dismiss the UIImagePickerController, returning control back to your application.  

UIImagePickerController

The UIImagePickerController is different from other view controllers. Rather than developers creating the controller’s view and adding components to the view’s canvas, the UIImage PickerController’s views are already created and are part of the UIKit library. Developers simply determine the controller’s source type and implement a delegate for the controller. The controller creates and manages the views while the delegate responds to the view being dismissed by a user.

Source

The iPod touch, as of this book’s publication, does not have a camera. The iPhone Simulator also lacks a camera. If you attempted to use an iPod touch’s nonexistent camera, you would obtain an exception. Attempting to use the camera on an iPhone Simulator results in a nonresponsive application after it logs a message to the debugger console (Figure 13-15). 2009-02-09 06:50:30.164 CameraProject[216:20b] photos can only be captured on HW To avoid an exception or nonresponsive application, the UIImagePickerController provides the isSourceTypeAvailable: method. + (BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType) sourceType This method returns YES if a source type is available and NO if unavailable. Valid source types are UIImagePickerControllerSourceTypePhotoLibrary, for selecting images from the photo library; UIImagePickerControllerSourceTypeCamera, for selecting images from the camera; and UIImagePickerControllerSourceTypeSavedPhotosAlbum, for selecting images from a camera roll, or from the photo library if the device doesn’t have a camera. After ensuring a device has a source type, you set the UIImagePickerController’s sourceType property. This property determines what controls the UIImagePickerController displays. Allowable source types are the same as with the isSourceTypeAvailable: method.  

Editing and Delegating

The controller also has an allowsImageEditing property and delegate property. The allowsImageEditing property determines if a user should be allowed to edit an image after taking or selecting the image. The delegate property specifies the class’s UIImagePicker ControllerDelegate.   Slide133  

 Figure 13-15 Using a camera on the iPhone Simulator results in a nonresponsive application.

 

 

UIImagePickerControllerDelegate

The UIImagePickerControllerDelegate’s protocol has two methods your delegate should implement for the image picker. The imagePickerController:didFinishPickingMediaWithInfo :info: method is called after a user selects an image. This could be selecting an image from a camera roll or photo library, or after taking a photo using the camera. The method’s signature follows.(void)imagePickerController:(UIImagePickerController *) picker didFinishPickingMediaWithInfo: (NSDictionary *) info; If you cancel a photo selected, the imagePickerControllerDidCancel: method is called. The method’s signature follows.(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker The imagePickerController:didFinishPickingMediaWithInfo: info: has three parameters. The first parameter holds a reference to the image picker, the second to the image picked, and the third parameter references an NSDictionary containing editing information. If editing is disabled, the third parameter holds nil. If editing is enabled, the parameter holds the unedited image and the cropped rectangle. For more information on the imagePickerController:didFinish PickingMediaWithInfo:info method, refer to Apple’s online UIImagePickerControllerDelegate Reference.    

Using the UIImagePickerController

NOTE

Using the camera or camera roll requires having an iPhone, a developer’s membership, and a provision for this example application. You can select a photo from a photo album using the iPhone Simulator, however. To accommodate more readers, this task limits itself to the iPhone Simulator’s photo library.

  1. Create a new View-based Name the project CameraProject.
  2. Open xib in Interface Builder.
  3. Drag a toolbar from the library onto the view’s
  4. Rename the first button Take Add another button to the toolbar and call it Select Photo. Add a UIImageView to the canvas (Figure 13-16).

     Slide134  

Figure 13-16 The application’s canvas

  1. Save and quit Interface Builder.
  2. Create a new NSObject called Modify the class so it adopts the UINavigationControllerDelegate and UIImagePickerControllerDelegate protocols (Listing 13-17). Add a property that contains the UIImage that the image picker will select.
  3. Implement the imagePickerController methods (Listing 13-18).
  4. Open h and import MyImagePickerDelegate. Add an IBOutlet for MyImagePickerDelegate and add an IBOutlet for the UIImageView added to the canvas (Listing 13-19).
  5. Add two IBActions to Name one action takePicture and the other selectPicture (Listing 13-20). Implement both methods as shown in Listing 13- 20.
  6. Implement the viewDidLoad method in CameraProjectViewController so the method ensures the camera is supported (Listing 13-20).

NOTE If running on the iPhone Simulator, comment the code in viewDidLoad that checks if a camera is available. Be certain to only click the Select Photo button.  

  1. Save and build.
  2. Open xib in Interface Builder.
  3. Connect the File’s Owner theImageView outlet to the UIImageView on the
  4. Connect the selectPicture action to the Select Photo button and the takePicture action to the Take Photo
  5. Drag an object from the library to the Document Change its type to MyImagePickerDelegate.
  6. Connect the File’s Owner imagePickerDelegate outlet to the newly created
  7. Save and exit Interface
  8. If you wish to use the camera, follow the necessary steps to register and provision the application so you can install it on your Otherwise, use the Select Photo button and select a photo from the SDK’s photo albums.
  9. Run the application. Everything works as expected, except notice that the view’s image is not set to the image selected by the image picker.

Listing 13-17 MyImagePickerDelegate.h #import <Foundation/Foundation.h> @interface MyImagePickerDelegate : NSObject <UINavigationController Delegate, UIImagePickerControllerDelegate> { UIImage * selectedImage; } @property (nonatomic, retain) UIImage * selectedImage; @end Listing 13-18 MyImagePickerDelegate.m #import "MyImagePickerDelegate.h" @implementation MyImagePickerDelegate @synthesize selectedImage; - (void) imagePickerControllerDidCancel: (UIImagePickerController *) picker { [picker.parentViewController dismissModalViewControllerAnimated: YES]; [picker release]; }(void)imagePickerController:(UIImagePickerController *) picker didFinishPickingMediaWithInfo:(NSDictionary *) info { selectedImage = (UIImage*)[info objectForKey:UIImagePickerControllerOriginalImage]; [picker.parentViewController dismissModalViewControllerAnimated: YES]; [picker release]; }(void) dealloc { [selectedImage release]; [super dealloc]; } @end Listing 13-19 CameraProjectViewController.h #import <UIKit/UIKit.h> #import "MyImagePickerDelegate.h" @interface CameraProjectViewController : UIViewController { IBOutlet MyImagePickerDelegate * imgPickerDelegate; IBOutlet UIImageView * theImageView; }   @property (nonatomic, retain) MyImagePickerDelegate * imgPickerDelegate; @property (nonatomic, retain) UIImageView * theImageView;

  • (IBAction) takePicture: (id) sender;
  • (IBAction) selectPicture: (id) sender;

@end Listing 13-20 CameraProjectViewController.m #import "CameraProjectViewController.h" @implementation CameraProjectViewController @synthesize imgPickerDelegate; @synthesize theImageView; - (void) viewDidLoad { [super viewDidLoad]; if(!([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera])) { NSLog(@"Camera not supported....quitting application"); UIAlertView * myAlert = [[UIAlertView alloc] initWithTitle:@"Camera Error" message:@"Camera Not Supported. Application will terminate." delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil]; [myAlert show]; [myAlert release]; //warning - terminate is undocumented api [[UIApplication sharedApplication] terminate]; } } - (IBAction) takePicture: (id) sender { UIImagePickerController * pickCont = [[UIImagePickerController alloc] init]; pickCont.delegate = imgPickerDelegate; pickCont.allowsImageEditing = YES; pickCont.sourceType = UIImagePickerControllerSourceTypeCamera; [self presentModalViewController:pickCont animated:YES]; NSLog(@"heynow"); } - (IBAction) selectPicture: (id) sender { UIImagePickerController * pickCont = [[UIImagePickerController alloc] init]; pickCont.delegate = imgPickerDelegate; pickCont.allowsImageEditing = YES; pickCont.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; [self presentModalViewController:pickCont animated:YES]; NSLog(@"heynow"); if(self.imgPickerDelegate.selectedImage != nil) self.theImageView.image = self.imgPickerDelegate.selectedImage; } - (void)dealloc { [theImageView release]; [imgPickerDelegate release]; [super dealloc]; } @end     Nothing happens after selecting or taking a photo, unless you click one of the application’s buttons a second time. The photo previously selected is then displayed (Figure 13-17). What is supposed to happen is that the theImageView in CameraProjectViewController should display the newly taken photo. You might think that placing the following lines in the selectPicture would solve the problem, but they do not. if(self.imgPickerDelegate.selectedImage != nil) self.theImageView.image = self.imgPickerDelegate.selectedImage; Notice the ―heynow‖ logging added to the delegate’s methods. Immediately after displaying the image picker, the debugger console logs ―heynow.‖ If the logging does not wait for the image picker to finish, the two lines setting the image don’t wait either, and so the image isn’t set correctly until the next time you push one of the application’s two buttons. CameraProjectController must be changed so it is notified when a picture is taken so it can update its view. There are two ways you might fix the image not displaying. First, you could add a reference to the CameraProjectViewController in MyImagePickerDelegate, but I dislike this solution. Why? Adding a CameraProjectViewController to MyImagePickerDelegate as a property introduces close coupling between the two classes. You can never again reuse MyImagePickerDelegate, unless you reuse CameraProjectViewController. Unacceptable. A better solution, in my humble opinion, is using a notification.

Notifications

If you have ever used Java listeners, you already know a notification’s basic workings. Cocoa’s notifications are similar to Java’s listeners, only easier and more flexible. Every Cocoa application has a notification center, NSNotificationCenter. Classes in your application can post notifications, NSNotification, to the notification center. Other classes can register with the notification center to listen for notifications. Through notifications, classes can communicate with each other without even knowing about one another’s existence. Although this book doesn’t present notifications with any detail, in the next few steps, you add a notification to the CameraProjectViewController.   Slide134Slide135                                         New Microsoft PowerPoint Presentation   Slide135                                   Slide136 Figure 13-17 Running the application in iPhone Simulator and using the provided photo library Refer to Apples Introduction to Notification Programming Topics for more information on using notifications.    

  1. Open CameraProject in Xcode.
  2. Modify the imagePickerController;didFinishPickingMediaWithInfo:info: method to post a

notification (Listing 13-21).

  1. Add a method called changeImage to CameraProjectViewController (Listing 13-22).
  2. Modify viewDidLoad so it observes the notification (Listing 13-23). Also, modify dealloc so it unregisters itself as a notification
  3. Click Build And Now the application sets the UIImageView’s image as expected.

  Listing 13-21 The didFinishPickingMediaWithInfo modified to post a notification - (void)imagePickerController:(UIImagePickerController *) picker didFinishPickingMediaWithInfo:(NSDictionary *) info { self.selectedImage = (UIImage*)[info objectForKey:UIImagePickerControllerOriginalImage]; [[NSNotificationCenter defaultCenter] postNotificationName:@"Image Picked" object:nil]; [picker.parentViewController dismissModalViewControllerAnimated:YES]; [picker release]; } Listing 13-22 The changeImage method - (void) changeImage { NSLog(@"IMAGE CHANGED"); self.theImageView.image = self.imgPickerDelegate.selectedImage; } Listing 13-23 The viewDidLoad method modified to have CameraViewController observe the notification - (void) viewDidLoad { [super viewDidLoad]; if(!([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera])) { NSLog(@"Camera not supported....quitting application"); UIAlertView * myAlert = [[UIAlertView alloc] initWithTitle:@"Camera Error" message:@"Camera Not Supported. Application will terminate." delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil]; [myAlert show]; [myAlert release]; //warning - terminate is undocumented api [[UIApplication sharedApplication] terminate]; } [[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(changeImage) name:@"ImagePicked" object:nil]; } - (void) dealloc { [super dealloc]; [theImageView release]; [imgPickerDelegate release]; [ [NSNotificationCenter defaultCenter] removeObserver:self]; } In this task, you created an application that uses the UIImagePickerController to control an iPhone’s camera. You created two buttons, one for taking a photo using the camera and one for selecting an image from the photo library. If you obtained provisioning for the application and installed the provisioning on your iPhone, you could install the application on your iPhone and use the camera (Figure 13-18). But instead, you selected photos from the photo library and ran the application on the iPhone Simulator.  

Figure 13-18 Using the camera on an iPhone

  Slide137     Slide138

You liked the article?

Like: 0

Vote for difficulty

Current difficulty (Avg): Medium

EasyMediumHardDifficultExpert
IMPROVE ARTICLEReport Issue

About Author

Authorlogo
Name
TekSlate
Author Bio

TekSlate is the best online training provider in delivering world-class IT skills to individuals and corporates from all parts of the globe. We are proven experts in accumulating every need of an IT skills upgrade aspirant and have delivered excellent services. We aim to bring you all the essentials to learn and master new technologies in the market with our articles, blogs, and videos. Build your career success with us, enhancing most in-demand skills in the market.

Stay Updated
Get stories of change makers and innovators from the startup ecosystem in your inbox