Showing posts with label UIImagePickerController. Show all posts
Showing posts with label UIImagePickerController. Show all posts

Saturday, 6 August 2016

Create Custom Camera



iOS provide UIIMagePickerController for getting an image from photo library and for capturing a new image. But iOS also provide a cool feature for creating custom camera. We can create custom camera using AVFoundation framework, which give direct access to the camera and microphone.
This process is managed through AVCaptureSession which coordinate the flow of data from input devices (such as camera, microphone) to outputs (Such as image and movie file).

Minimally we need:

1) An instance of AVCaptureDevice to present the input device, such as a camera and microphone.
2) An instance of a concrete subclass of AVCaptureInput to configure the ports from the input device.
3) An instance of a concrete subclass of AVCaptureOutput to manage the output to a movie file or  still image.
4) An instance of AVCaptureSession to coordinate the data flow from input to output.
5) An instance of AVCaptureVideoPreviewLayer to display a preview of what the camera is recording.



Start session:

    self.session = [[AVCaptureSession alloc] init]; //initialize an instance of AVCaptureSession
    [self.session setSessionPreset:AVCaptureSessionPresetHigh];
//Indicates the session preset currently in use by the receiver.

Capture Device: 

An AVCaptureDevice represents a physical device that provides realtime input media data, such as video and audio. A input device can be the camera or microphone.
       
AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

 Capture Device Input:

AVCaptureDeviceInput is a concrete subclass of AVCaptureInput that provides an interface for capturing media from an AVCaptureDevice.

       self.captureDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:&error];

Now add capture device input to session
      if ( [self.session canAddInput:self.captureDeviceInput] )
            [self.session addInput:self.captureDeviceInput];


Preview:

AVCaptureVideoPreviewLayer quickly render the raw data collected by the camera on the screen, means we can also say, AVCaptureVideoPreviewLayer  is display a preview of what the camera is capturing.
AVCaptureVideoPreviewLayer is a subclass of CALayer that we add as a sublayer of preview view's layer.

AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
    [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
   
    CALayer *rootLayer = [[self view] layer];
    [rootLayer setMasksToBounds:YES];
    [previewLayer setFrame:CGRectMake(0, 0, rootLayer.bounds.size.height, rootLayer.bounds.size.height)];
    [self.PreviewView.layer insertSublayer:previewLayer atIndex:0];


Now, Its enough for display camera recording on screen.

Start the session

[self.session startRunning];

Run the app and check.


Now add a UIButton to the view for capture rendered raw data as a image.

and, for manage the output to a still image create an instance of AVCaptureStillImageOutput and add to session.
AVCaptureStillImageOutput is a concrete subclass of AVCaptureOutput that can be used to capture high-quality still images with accompanying metadata.

AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
    if ([self.session canAddOutput:stillImageOutput])
    {
        [stillImageOutput setOutputSettings:@{AVVideoCodecKey : AVVideoCodecJPEG}];
        [self.session addOutput:stillImageOutput];
        [self setStillImageOutput:stillImageOutput];
    }


(Add above code before start the session)

Now add button method for capture image,

-(IBAction)captureButtonAction:(id)sender{
    //capture preview image
    [[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
       
        if (imageDataSampleBuffer)
        {
            //get image data from buffer
            NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
            UIImage *image = [[UIImage alloc] initWithData:imageData];
        

//save image to photo library (if you want to save captured image)
            [[[ALAssetsLibrary alloc] init] writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)[image imageOrientation] completionBlock:nil];
        }
    }];
}


Now its time to capture fresh image.
Run the app and capture image.


Now Add another method for swap camera(front to back and back to front)
#pragma mark -
-(IBAction) changeCameraAction:(id)sender{
    //disable button
    self.captureButton.enabled = NO;
    self.swapButton.enabled = NO;
    //get current input device
    AVCaptureDevice *currentDevice = self.captureDeviceInput.device;
    AVCaptureDevicePosition preferredPosion = AVCaptureDevicePositionUnspecified;
    AVCaptureDevicePosition currentPosition = currentDevice.position
    ;
    //get new preferred position
    switch (currentPosition) {
        case AVCaptureDevicePositionUnspecified:
            break;
        case AVCaptureDevicePositionBack:
            preferredPosion = AVCaptureDevicePositionFront;
            break;
        case AVCaptureDevicePositionFront:
            preferredPosion = AVCaptureDevicePositionBack;
            break;
    }//end switch case
   
//configure new input device
    AVCaptureDevice *captureDevice = [self deviceWithMediaType:AVMediaTypeVideo withPreferredPosition:preferredPosion];
    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:nil];
    //update session
    [self.session beginConfiguration];
    // Remove the existing device input first, since using the front and back camera simultaneously is not supported.
    [self.session removeInput:self.captureDeviceInput];
   
    if ( [self.session canAddInput:deviceInput] ) {
       
        [self.session addInput:deviceInput];
        self.captureDeviceInput = deviceInput;
    }
    else {
        [self.session addInput:self.captureDeviceInput];
    }
    [self.session commitConfiguration];
    //enable button
    self.captureButton.enabled = YES;
    self.swapButton.enabled = YES;
}
-(AVCaptureDevice *) deviceWithMediaType:(NSString *)mediaType withPreferredPosition:(AVCaptureDevicePosition) position{
    NSArray *devices = [AVCaptureDevice devicesWithMediaType:mediaType];
    AVCaptureDevice *captureDevice = devices.firstObject;
   
    for ( AVCaptureDevice *device in devices ) {
        if ( device.position == position ) {
            captureDevice = device;
            break;
        }
    }
    return captureDevice;
}


Click here for complete project.

Friday, 4 March 2016

UIImagePickerController in Swift

UIImagePickerController  class manages customizable, system-supplied user interface for taking pictures and movies, and for choosing saved images and movies for use in the app. A UIImagePickerController manages user interactions and delivers the results of those interactions to a delegate object.
For more details Click here.

To use an image picker controller with in the app, perform these steps:

1) Verify that the device is capable of picking content from the desired source.
2) Check which media types are available for the source type using.
3) Adjust image picker controller's UI according to media type
4) Present user interface.


Code:

// MARK: - Open Camera
    func openCamera(source:UIImagePickerControllerSourceType){


//Check source type available or not
        if(UIImagePickerController.isSourceTypeAvailable(source) == false){
            return;
        }

//Create new object of UIImagePickerContrller
        let imagepickerController = UIImagePickerController()
       imagepickerController.sourceType = source
        imagepickerController.delegate = self

//Present UIImagePickerContrller user interface
        self.presentViewController(imagepickerController, animated: true, completion: nil)
    }


//MARK: - Image Picker Delegate
    func imagePickerControllerDidCancel(picker: UIImagePickerController) {
        nameTitlelabel.hidden = false
        //dismiss image picker controller view
        picker.dismissViewControllerAnimated(true, completion: nil)
    }


    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {

//Get selected image
        let seletctedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
        patientImageView.image = seletctedImage

//dismiss image picker controller view
        picker.dismissViewControllerAnimated(true, completion: nil)
    }