Presenting camera roll UIImagePickerController over open camera - ios

On my app I have a cameraOverlayView over my open camera with custom controls for the camera buttons. The app allows the user to take several pictures before closing the camera, so the shutter button does not call dismissViewControllerAnimated, instead there's a close button for when you're done taking pictures.
Now, one of the buttons on the camera overlay is a gallery button to allow the user to pick a saved image instead of shooting a new one. I've tried two different approaches to make this work, both failed.
First approach
Use the same UIImagePickerController instance that is currently presenting the overlay and switch the sourceType to library. It does present the gallery then, but when a photo is tapped, I can't dismiss the galley without dismissing the whole overlay.
Second approach
Create a separate instance of UIImagePickerController, set the sourceType to gallery and attempt to call presentViewController, which then fails with the warning:
"Warning: Attempt to present on
whose view is not in the window
hierarchy!"
Does anyone have a solution for this issue? Is this even possible?

Try this~~ I think it is your goal.
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong) UIImagePickerController *imagePicker;
#end
#implementation ViewController
#synthesize imagePicker = _imagePicker;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
sleep(2);
_imagePicker = [[UIImagePickerController alloc] init];
[_imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[_imagePicker setDelegate:self];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 50, 100, 30)];
[button setTitle:#"Library" forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor darkGrayColor]];
[button addTarget:self action:#selector(gotoLibrary:) forControlEvents:UIControlEventTouchUpInside];
[_imagePicker.view addSubview:button];
[self presentViewController:_imagePicker animated:YES completion:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)gotoLibrary:(id)sender
{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
[imagePicker.view setFrame:CGRectMake(0, 80, 320, 350)];
[imagePicker setSourceType:UIImagePickerControllerSourceTypeSavedPhotosAlbum];
[imagePicker setDelegate:self];
[_imagePicker presentViewController:imagePicker animated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissViewControllerAnimated:YES completion:nil];
}
#end

The second approach is correct.
I don't see your code, but I think that your controller hierarchy is something similar to this:
Main VC ---present---> Camera VC
so, if you call
[self presentViewController:picker animated:YES completion:^{}];
from your Main VC, you are attempting to show another VC from an "hidden" one (covered by the Camera VC).
The key is to take a reference to your camera VC (let's call it cameraVC) and do something similar from Main VC:
[cameraVC presentViewController:theOtherPicker animated:YES completion:^{}];
doing this, the "present" action is done by the Camera VC (visible) without warnings, and not by the hidden Main VC.

You could code your own custom gallery views for selecting photos and then add that to the cameraOverlayView subview hierarchy.
There must be open source projects on GitHub, which show how to make these views, somewhere. Alternatively, I happen to have released a control very similar to what you are looking for if you don't want to start from scratch.
It's quite a simple procedure really — a collection view with a datasource backed by the AssetsLibrary framework.

I would set up a capture session as follows:
- (void)setupCaptureSession
{
NSError* error = nil;
// Create the session
_captureSession = [[AVCaptureSession alloc] init];
_captureSession.sessionPreset = AVCaptureSessionPresetMedium;
AVCaptureDevice* device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput* input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
[_captureSession addInput:input];
AVCaptureVideoDataOutput* output = [[AVCaptureVideoDataOutput alloc] init];
[_captureSession addOutput:output];
// Configure your output.
dispatch_queue_t queue = dispatch_queue_create("myCameraOutputQueue", NULL);
//If you want to sebsequently use the data, then implement the delegate.
[output setSampleBufferDelegate:self queue:queue];
}
Having done that, you can create a preview layer as follows:
_previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_captureSession];
[_captureSession startRunning];
And then add the preview layer to your view:
_myView.layer addSubLayer:_previewLayer];
Now that you have this set up, I'd add a custom image picker, such as this one: https://github.com/arturgrigor/AGImagePickerController

I present a custom camera view controller, onto which I add a "SourceTypeCamera" UIImagePickerController as a contained child view controller. My custom view controller has a button that in turn adds another UIImagePickerController instance, this one a "SourceTypePhotoLibrary".
You end up with a nested view controller hierarchy:
root/main view controller — presents:
my custom camera view controller – adds as child view controller:
either camera or photo-library UIImagePickerController
Something like this:
- (void)viewDidLoad { (id<UIImagePickerControllerDelegate,UINavigationControllerDelegate>)theDelegate {
[super viewDidLoad];
[self startImagePickerWithSourceType:UIImagePickerControllerSourceTypeCamera
delegate:self];
// configure button in camera overlay to call -pickPhotoTapped
}
- (void) pickPhotoTapped {
[self startImagePickerWithSourceType:UIImagePickerControllerSourceTypePhotoLibrary
delegate:self];
}
- (BOOL) startImagePickerWithSourceType:(UIImagePickerControllerSourceType)sourceType
delegate:(id<UIImagePickerControllerDelegate,UINavigationControllerDelegate>)theDelegate {
if (([UIImagePickerController isSourceTypeAvailable:sourceType] == NO)
|| (theDelegate == nil))
return NO;
self.cameraUI = [[UIImagePickerController alloc] init];
self.cameraUI.sourceType = sourceType;
self.cameraUI.view.frame = self.view.bounds;
self.cameraUI.delegate = theDelegate;
if (sourceType == UIImagePickerControllerSourceTypeCamera) {
self.cameraUI.allowsEditing = NO;
self.cameraUI.showsCameraControls = NO;
self.cameraUI.cameraOverlayView = [self overlayView];
}
[self addChildViewController:self.cameraUI];
[self.view addSubview:self.cameraUI.view];
[self.cameraUI didMoveToParentViewController:self];
return YES;
}

Related

xCode Creating UIImagePickerController and Referencing It

for my app I want to create a custom camera overlay and create a UIImagePickerController to start recording video. (below)
- (IBAction)RecordVideo:(UIButton *)sender {
//initialise camera view
UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
cameraUI.cameraDevice = UIImagePickerControllerCameraDeviceFront;
cameraUI.showsCameraControls = NO;
cameraUI.navigationBarHidden = YES;
cameraUI.toolbarHidden = YES;
OverlayView *overlay = [[OverlayView alloc]
initWithFrame:CGRectMake(0, 0, 20,20)];
cameraUI.cameraOverlayView = overlay;
[self presentViewController:cameraUI animated:YES completion:nil];
}
as part of the cameraOverlayView I've instantiated a UIButton:
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
//clear the background color of the overlay
self.opaque = NO;
self.backgroundColor = [UIColor clearColor];
... some overlay UI stuff
UIButton *captureBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
UIImage *captureBtnImg = [UIImage imageNamed:#"captureBtn.png"];
[captureBtn setBackgroundImage:captureBtnImg forState:UIControlStateNormal];
captureBtn.frame = CGRectMake(self.frame.size.width/2 - 15,
430,
80,
80);
[self addSubview:captureBtn];
}
return self;
}
So how do I create an IBAction for this button which can then make the UIImagePickerController cameraUI start recording?
If somebody could also explain to me how the IBActions are called from specific buttons only that would also be amazing because that seems like black magic to me?
You can add target like this,
[captureBtn addTarget:self action:#selector(captureBtnclick:) forControlEvents:UIControlEventTouchUpInside];
and you action method shoulbe like this
-(void)captureBtnclick :(UIButton*)sender{
//handle your task on click here
}
second thing why you are adding layer on it? you can use default video recording from imagePicker by setting mediatype like
cameraUI.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];
Update accroding to comment
you can use on button click,
[picker startVideoCapture]; //in your case cameraUI i think
Update 2 :
in your .h file,
#property UIImagePickerController *cameraUI;
then in your method RecordVideo use like,
self.cameraUI = [[UIImagePickerController alloc] init];
self.cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
//etc.....
By this way you can use camaraUI in whole class by self
hope this will help :)

capture image is not working properly.?

Hi I am very new to developing iOS application please help me. i am facing a problem regarding capturing image by using UIImagePicker. I have integrated hip mob app in to our application.
In that window i want to show a UIButton so that the user click on that UIButton should capture the image. when i click on the button its throwing an message as (whose view is not in the window hierarchy!).
I think this happens due to this chat window. here is my code snippet.!
[[HMService sharedService] openChat:self withSetup:^(HMChatViewController * controller)
{
controller.chatDelegate = self;
controller.chatView.receivedMessageFont = [UIFont systemFontOfSize:20.0];
controller.navigationBarHidden = YES;
UIView * viewObjForVehicleDetails = [[UIView alloc]init];
UIButton * btnForCaputrePhoto = [[UIButton alloc]init];
[btnForCaputrePhoto addTarget:self action:#selector(CapturePhotoImage) forControlEvents:UIControlEventTouchUpInside];
btnForCaputrePhoto.frame = CGRectMake(55, 90, 103, 85);
[controller.chatView addSubview:viewObjForVehicleDetails];
[viewObjForVehicleDetails addSubview:btnForCaputrePhoto];
[[controller.chatView table] registerClass:[ChatTableViewCell class] forCellReuseIdentifier:#"ReuseChatTableViewCell"];
}
-(void)CapturePhotoImage
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:NO completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:NULL];
}
Thanks in Advance.!
First be sure you are using the following delegate in your view controller
<UINavigationControllerDelegate, UIImagePickerControllerDelegate>
Secondly use this line to show the ImagePicker:-
[self presentModalViewController:picker animated:YES];
Alternative Way:-
[self.view addSubview:imagePicker.cameraOverlayView]
Change the method declaration as follows
- (IBAction) CapturePhotoImage:(id)sender
{
NSLog("Called");
}
And the method call "CapturePhotoImage" as CapturePhotoImage:
[btnForCaputrePhoto addTarget:self action:#selector(CapturePhotoImage:) forControlEvents:UIControlEventTouchUpInside];

Disable camera rotation in iOS?

My code to add a UIImagePickerController:
picker = [[[UIImagePickerController alloc] init] autorelease];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.showsCameraControls = NO;
[self displayContentController:picker inView:cameraBoxView];
[self.view sendSubviewToBack:picker.view];
- (void)displayContentController:(UIViewController *)content inView:(UIView *)v {
//Delete the previous instance of the same view controller
for (UIViewController *vc in self.childViewControllers) {
if ([vc isKindOfClass:[content class]]) {
[vc removeFromParentViewController];
}
}
[self addChildViewController:content];
content.view.frame = v.frame;
[self.view addSubview:content.view];
[content didMoveToParentViewController:self];
if ([content isKindOfClass:[CCInnerNavigationController class]]) {
innerNavigationController = (CCInnerNavigationController *)content;
}
}
I have disabled all the device orientations except of portrait. But the image from camera is rotated. How to solve this issue in both iOS 6 and 7.
P.S. I understand that there are a lot of soludions but it seems they are too old because NOTHING of them works.
When you instatiate the UIImagePickerController you must also pass it a delegate. The delegate should be conform to 2 protocols UIImagePickerControllerDelegate and UINavigationControllerDelegate. The second makes possible to add some logic for rotation at runtime, implement this methods accordingly to what you want to achieve.
– navigationControllerPreferredInterfaceOrientationForPresentation:
– navigationControllerSupportedInterfaceOrientations:
I changed the following code:
imgView.image = img;
to:
imgView.image = [UIImage imageWithCGImage:img.CGImage scale:1 orientation:UIImageOrientationRight];
And now it works in both iOS 6 and 7. I don't know how it fixes this bug but it really works. Maybe image picker corrupts the image or image view and this code fixes it by creating a new image instance.

Take two images within Camera App

im pretty newish to this kind of coding but have learnt a fair bit and have unfortunately hit a bump in an app im working on.
I am trying to create a camera application that will allow the user to take a 'before' image, then take an 'after' image, I would then like the option for the images to be put together (left and right) and saved as one image.
So far I have managed to code the app to take a single picture with the code below:
HEADER:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
#property (strong, nonatomic) IBOutlet UIImageView *beforeImage;
- (IBAction)cameraBeforeImage:(UIButton *)sender;
- (IBAction)libraryBeforeImage:(UIButton *)sender;
- (IBAction)deleteBeforeImage:(UIButton *)sender;
#property (strong, nonatomic) IBOutlet UIImageView *afterImage;
- (IBAction)cameraAfterImage:(UIButton *)sender;
- (IBAction)libraryAfterImage:(UIButton *)sender;
- (IBAction)deleteAfterImage:(UIButton *)sender;
- (IBAction)saveImages:(UIButton *)sender;
#end
IMPLEMENTATION:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)cameraBeforeImage:(UIButton *)sender {
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle:#"Oops!"
message:#"This Device Has No Camera, Please Select An Image From Your Library."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[myAlertView show];
}else{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:NULL];
}
}
- (IBAction)libraryBeforeImage:(UIButton *)sender {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:picker animated:YES completion:NULL];
}
- (IBAction)deleteAfterImage:(UIButton *)sender {
}
- (IBAction)saveImages:(UIButton *)sender {
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
self.beforeImage.image = chosenImage;
[picker dismissViewControllerAnimated:YES completion:NULL];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:YES completion:NULL];
}
- (IBAction)deleteBeforeImage:(UIButton *)sender {
}
- (IBAction)cameraAfterImage:(UIButton *)sender {
}
- (IBAction)libraryAfterImage:(UIButton *)sender {
}
- (IBAction)saveImages:(UIButton *)sender {
}
#end
Here is the list of things I need to add, any help on any of them would be very much appreciated!
Add the same functionality to the 'After' buttons as the 'Before' but to store the image in the 'afterImage' Image view.
Add functionality to the 'saveImages' button to save the two taken images as one image stitched together.
Thank you all in advance!
1 . The first problem, I guess you question is 'How do you know which picture was taken and where to display it'?
Answer1: Create two UIImagePickerControllers as properties. Once imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info returns an image you can simply check which controller was it if( picker == afterPictureController){....
Answer2: Create a flag indicating whether the next taken picture will be an after or a before picture. It's not very flexible but it works.
2 . To stitch two images, you can create UIGraphicsBeginImageContext with size(image1Width+image2Width, MAX(image1Height, image2Height)) and draw image using the context. After that, you can get the stitched image from the context by calling UIGraphicsGetImageFromCurrentImageContext();

Sorting a Picture to a Specific Place in the app

I want it to flow like this I'm doing it tons of times and dosent work.
User pushes the photo button in the app and takes picture.
After taking the picture users has to input detail. sorts options comes out where user can pick 8 different default genre's, and user pushes save.
It goes back to the Home Screen and the User can see the 8 different genre in button & when pushed pictures comes out as a coverflow(flow cover) that is saved in the app. I want to make it work like the above but dosent work.
My Code is until now is:
#implementation ViewController
-(IBAction)TakePhoto {
picker = [[UIImagePickerController alloc]init];
picker.delegate = self;
[picker setSourceType: UIImagePickerControllerSourceTypeCamera ];
[self presentViewController:picker animated:YES completion:NULL];
}
-(IBAction)ChooseExisting{
picker2 = [[UIImagePickerController alloc]init];
picker2.delegate = self;
[picker2 setSourceType: UIImagePickerControllerSourceTypePhotoLibrary];
[self presentViewController:picker2 animated:YES completion:NULL];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:
(NSDictionary *) info {
image = [info objectForKey:UIImagePickerControllerOriginalImage] ;
[imageview setImage:image];
[self dismissViewControllerAnimated:YES completion:NO];
}
- (void) imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[self dismissViewControllerAnimated:YES completion:NULL];
}
#end
#implementation CVCLCoverFlowLayout
-(NSInteger)count {
return [self.collectionView numberOfItemsInSection:0 ];
}
-(CGSize)collectionViewContentSize{
CGSize size = self.collectionView.bounds.size;
size.width = self.count * self.cellInterval;
return size;
}
You are not saving the image you clicked in the delegate function .and when you want to use the saved image then you need to write down the code for same .:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:
(NSDictionary *) info {
image = [info objectForKey:UIImagePickerControllerOriginalImage] ;
[imageview setImage:image];
/ save the image to local storage of your application /
[self dismissViewControllerAnimated:YES completion:NO];
}
You can check the code for same over :
http://dcraziee.wordpress.com/2013/05/20/how-to-save-and-get-image-from-cache-directory/
Please share the blog if you like it.

Resources