Tuesday, July 16, 2013

Objective-C > Photo & Camera



In this lesson, you should learn the following:

  1. The photos and movies accessed by the users through the Photos app constitute the photo library, through the UIImagePickerController class.
  2. The Assets Library framework lets you access the photo library and its contents programmatically. You’ll need to link to AssetsLibrary.framework and import <AssetLibrary/AssetsLibrary.h>
  3. The UIImagePickerController class can also be used to give the user an interface similar to the Camera app, letting the user take photos and videos on devices with the necessary hardware.

At a deeper level, AV Foundation provides direct control over the camera hardware. You’ll need to link to AVFoundation.framework and import <AVFoundation/AVFoundation.h>
To use constants such kUITypeImage, your app must link to MobileCoreServices.framework and import <MobileCoreServices/MobileCoreServices.h>

<UIImagePickerController class>
UIIMagePickerController class is a view controller (UINavigationController) whose view provides a navigation interface, similar to the Photo app, in which the user can choose an item from the photo library, Alternatively (二擇一地), it can provide an interface, similar to the Camera app, for taking a video or still photo if the necessary hardware is present.
On the iPhone>
On the iPad>
        <Some exception may be occurred...>

The role and appearance of an image picker controller depend on the source type you assign to it before you present it.
(class method) isSourceTypeAvailable:
-       Return BOOL; If return NO, don’t present the controller with that source type?
-       If NO, if the user’s device has no camera or the camera is unavailable.
-       If YES, call the following class method in order to learn whether the user can take a still photo (kUITypeImage), a video (kUITypeMovie), or both.

(class method) availableMediaTypesForSourceType:
-       to specify an array of mediaTypes you’re interested in. This array will usually contain kUITypeImage, kUITypeMovie, or both.

Steps:
1. Check isSourceTypeAvailable.
2. If return YES, call availableMediaTypesForSourceType:
3. Instantiate UIImagePickerController, set its sourceType to UIImagePickerControllerSourceTypeCamera, and set its mediaTypes
4. Set a delegate and present the view controller.
5. When the view controller appears, the user will see the interface for taking a picture, familiar from the Camera app, possibly including flash button, camera selection button, and digital zoom, still/video switch, and Cancel and Shutter buttons.
6. For picture, has retake button as well?

Example:
<Functional and UI Design>
UI consists of an image view and a toolbar containing two buttons: - left button is used to display the camera to the user and allow a photograph to be taken which will subsequently be displayed in the image view. Right button is used to provide access to the camera roll where the user may select an existing photo image. Those new image taken with the camera through this app, they will be saved to the camera roll.

Technical steps:
1. Create a new project using the Single View Application template with Storyboard and Automatic Reference Counting optioned enabled, named it as Camera.
2. Drag an Image View object and a toolbar inside with 2 buttons.
  • Name the two button objects as userCamera and useCameraRoll.
  • Name the image view object as imageView.
3. 3 steps to setup Objects,
        a) Edit the CameraViewController.h file:
-       import MobileCoreSevices framework
#import <UIKit/UIKit.h>
#import <MobileCoreServices/MobileCoreServices.h>

@interface CameraViewController : UIViewController
<UIImagePickerControllerDelegate,
         UINavigationControllerDelegate>

@property BOOL newMedia;
@property (strong, nonatomic) IBOutlet UIImageView *imageView;

- (IBAction)useCamera:(id)sender;
- (IBAction)useCameraRoll:(id)sender;
@end
       
        b) Edit the CameraViewController.m file:
#import “CameraViewController.h”

@implementation CameraViewController
- (void) userCamera: (id)sender
{
if ([UIImagePickerController isSourceTypeAvailable:
           UIImagePickerControllerSourceTypeCamera])
    {
           UIImagePickerController *imagePicker =
             [[UIImagePickerController alloc] init];
           imagePicker.delegate = self;
           imagePicker.sourceType =
             UIImagePickerControllerSourceTypeCamera;
           imagePicker.mediaTypes = @[(NSString *) kUTTypeImage];
           imagePicker.allowsEditing = NO;
           [self presentViewController:imagePicker
             animated:YES completion:nil];
           _newMedia = YES;
     }
}
...
...
@end
- Call class method [+] (BOOL) isSourceTypeAvailable: (UIImagePickerControllerSourceType);
§  Check the device on which the application is running has a camera.
-  Create a UIImagePickerController instance;
-   Assign the cameraViewController as the delegate for the object
-  Define the media source as the camera;
-   Define the media type with kUITypeImage into an array only;
-   Set the newMedia flag to YES:
§  Indicate that the image is new and is not an existing image from the camera roll.
- (void) useCameraRoll:(id)sender
{
    if ([UIImagePickerController isSourceTypeAvailable:
          UIImagePickerControllerSourceTypeSavedPhotosAlbum])
    {
       UIImagePickerController *imagePicker =
           [[UIImagePickerController alloc] init];
       imagePicker.delegate = self;
       imagePicker.sourceType =
           UIImagePickerControllerSourceTypePhotoLibrary;
        imagePicker.mediaTypes = @[(NSString *) kUTTypeImage];
       imagePicker.allowsEditing = NO;
       [self presentViewController:imagePicker
           animated:YES completion:nil];
       _newMedia = NO;
    }
}
- Call class method [+] (BOOL) isSourceTypeAvailable: (UIImagePickerControllerSourceType);
-  Create a UIImagePickerController instance;
-  Assign the cameraViewController as the delegate for the object
-  Define the media source as the camera;
-  Define the media type with kUITypeImage into an array only;
-  Set the newMedia flag to NO:
§  Since the photo is already in the library we don’t need to save it again.

5. Implementing the Delegate Methods:
(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info delegate method is called when the user has finished taking or selecting an image.
#pragma mark -
#pragma mark UIImagePickerControllerDelegate

-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
   NSString *mediaType = info[UIImagePickerControllerMediaType];

   [self dismissViewControllerAnimated:YES completion:nil];

    if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
        UIImage *image = info[UIImagePickerControllerOriginalImage];

        _imageView.image = image;
        if (_newMedia)
            UIImageWriteToSavedPhotosAlbum(image,
               self,
               @selector(image:finishedSavingWithError:contextInfo:),
               nil);
        }
        else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
        {
                // Code here to support video if enabled
        }
}

-(void)image:(UIImage *)image
finishedSavingWithError:(NSError *)error
contextInfo:(void *)contextInfo
{
   if (error) {
        UIAlertView *alert = [[UIAlertView alloc]
           initWithTitle: @"Save failed"
           message: @"Failed to save image"
           delegate: nil
           cancelButtonTitle:@"OK"
           otherButtonTitles:nil];
        [alert show];
   }
}
- (void)imagePickerControllerDidCancel: delegate method is called if the user cancels the image picker session without taking a picture or making an image selection. In most cases, all this method needs to do is dismiss the image picker.
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
   [self dismissViewControllerAnimated:YES completion:nil];
}


Additional camera features:
...

No comments:

Post a Comment