grab image displayed on the UIImagePickerController without the overlay - iphone

I'm using UIImagePickerController with the camera as the sourceType. I am also drawing a custom overlay on the picker using the built-in overlay functionality(picker.overlay = myOverlay).
How can I get an UIImage of the camera, excluding my overlay?. I tried using UIGetScreenImage() but that captures my overlay as well.

[picker takePicture];

Related

MPMoviePlayerController dismisses my UIImagePickerController

I have an iPhone app where I load an UIImagePickerController onto a UIViewController. I then have a custom view on top of the camera. Now when the user takes a photo it is loaded onto a UIImageView which presents it to the user asking if you want to use that photo or take another (removing the image from the UIImageView). This works perfectly.
Now If the user has just recorded a video I wanted to take a snapshot preview somewhere in the video and present it as a static image in the same UIImageView. I do this with the following code:
MPMoviePlayerController *videoPlayer = [[MPMoviePlayerController alloc] init];
videoPlayer.shouldAutoplay = NO;
[videoPlayer setContentURL:[info valueForKey:UIImagePickerControllerMediaURL]];
UIImage *videoScreenShot = [videoPlayer thumbnailImageAtTime:(videoPlayer.duration/2.0) timeOption:MPMovieTimeOptionNearestKeyFrame];
photoPreview.image = videoScreenShot;
[videoPlayer release]
This works as intended. The problem is if I want to take another video. When I call:
[videoPlayer setContentURL:[info valueForKey:UIImagePickerControllerMediaURL]];
The camera shutter closes and the camera is seemingly dismissed. Trying to take a picture or recording video gives me:
UIImagePickerController: ignoring request to take picture; camera is not yet ready.
UIImagePickerController: ignoring request to start video capture; camera is not yet ready.
I've tried calling the following after, which has no effect:
myImagePicker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType: UIImagePickerControllerSourceTypeCamera];
[myImagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
I tried adding the UIImagePickerController to the UIIViewController again, which caused some fantastic freeze-ups.
Finally I tried commenting out the UIViewController's [super didReceivedMemoryWarning] line of didReceivedMemoryWarning. Which also had no effect.
I'm guessing MPMoviePlayerController takes over something UIImagePicker also needs. How do I give it back?
I would suggest setting your MPMoviePlayerController to nil before showing the UIImagePickerController, or maybe taking its view out of the interface temporarily. Both of these contain a movie player view, but there can be only one movie player view at a time in your application's interface. Thus they can interfere with each other, and that might be what's happening to you.

Access Camera in Same View

When we use UIImagePickerController to get camera action we need to open it in different viewController like as:
UIImagePickerController *imagepicker;
[self presentModalViewController:imagepicker animated:YES];
but I want to use this in same View controller from where this UIImagePickerController is called in different View.
Is it possible?
Try creating a view where you want the image picker to appear say destView.
Create the image picker and then use [destView addSubview: imagepicker.view]
You may need to play with size of destView to get things right.

AVCaptureVideoPreviewLayer: taking a snapshot

I'm trying to emulate the animation seen in the default camera app, where a snapshot of the cameras viewfinder is animated into the corner of the apps display.
The AVCaptureVideoPreviewLayer object that holds the key to solving this problem isn't very open to these requirements: trying to create a copy of it in a new layer with ..
- (id)initWithLayer:(id)layer
.. returns an empty layer, without the image snapshot, so clearly there is some deeper magic going on here.
Your clues/boos are most welcome.
M.
facing the same woes, from a slightly different angle.
Here are possible solutions, that none are too great IMO:
You can add to an AVCaptureSession both an AVCaptureStillImageOutput and an AVCaptureVideoDataOutput. When you set the sessionPreset to AVCaptureSessionPresetHigh you'll start getting frames by the API, and when you switch to AVCaptureSessionPresetPhoto you can take real images. So right before taking the picture, you can switch to video, get a frame, and then return to camera. Major caveat is that it takes a "long" time (couple of seconds) for the camera to switch between the video camera and picture camera.
Another option would be to use only the camera output (AVCaptureStillImageOutput), and use UIGetScreenImage to get a screen capture of the phone. You could then crop out the controls and leave only the image. This gets complicated if you're showing UI controls over the image. Also, according to this post, Apple started rejecting apps that use this function (it was always iffy).
Aside from these I also tried playing with AVCaptureVideoPreviewLayer. There's this post to save a UIView or CALayer to a UIImage. But it all produces clear or white images. I tried accessing the layer, the view's layer, the superlayer, the presentationLayer, the modelLayer, but to no avail. I guess the data in AVCaptureVideoPreviewLayer is very internal, and not really part of the regular layer infrastructure.
Hope this helps,
Oded.
I think you should add an AVCaptureVideoDataOutput to the current session with:
AVCaptureVideoDataOutput *videoOutput = [[AVCaptureVideoDataOutput alloc] init];
videoOutput.videoSettings = #{ (NSString *)kCVPixelBufferPixelFormatTypeKey : #(kCVPixelFormatType_32BGRA) };
[session addOutput:videoOutput];
dispatch_queue_t queue = dispatch_queue_create("MyQueue", NULL);
[videoOutput setSampleBufferDelegate:self queue:queue];
dispatch_release(queue);
Then, implement the delegate method below to get your image snapshot:
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
UIImage *image = [self imageFromSampleBuffer:sampleBuffer];
// Add your code here that uses the image.
dispatch_async(dispatch_get_main_queue(), ^{
_imageView.image = image;
});
}
This will consume memory and reduce the performance of the app. To improve, you can also optimize your AVCaptureVideoDataOutput with:
videoOutput.minFrameDuration = CMTimeMake(1, 15);
You can also use alwaysDiscardsLateVideoFrames.
there are 2 ways to grab frames of the preview.. AVCaptureVideoDataOutput & AVCaptureStillImageOutput :)
is your capture session is setup to grab video frames, then make your layer with the cgimage from a chosen frame. if it's setup for stills, wait until getting your still image and make your layer from a scaled down version of that cgimage. if you don't have an output on your session yet, you'll have to add one i think.
Starting in iOS 7, you can use UIView::snapshotViewAfterScreenUpdates to snapshot the UIView wrapping your AVCaptureVideoPreviewLayer. This is not the same as UIGetScreenImage, which will get your app rejected.
UIView *snapshot = [self.containerView snapshotViewAfterScreenUpdates:YES];
Recall the old-school way of turning a view into an image. For some reason it worked on everything except for camera previews:
UIGraphicsBeginImageContextWithOptions(self.containerView.bounds.size, NO, [UIScreen mainScreen].scale);
[self.containerView drawViewHierarchyInRect:self.containerView.bounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Show camera stream while AVCaptureSession's running

I was able to capture video frames from the camera using AVCaptureSession according to http://developer.apple.com/iphone/library/qa/qa2010/qa1702.html. However, it seems that AVCaptureScreen captures frames from the camera without showing the camera stream on the screen. I would like to also show camera stream just like in UIImagePicker so that the user knows that the camera is being turned on and sees what the camera is pointed at. Any help or pointer would be appreciated!
AVCaptureVideoPreviewLayer is exactly what you're looking for.
The code fragment Apple uses to demonstrate how to use it is:
AVCaptureSession *captureSession = <#Get a capture session#>;
AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:captureSession];
UIView *aView = <#The view in which to present the layer#>;
previewLayer.frame = aView.bounds; // Assume you want the preview layer to fill the view.
[aView.layer addSublayer:previewLayer];

Library photos as source to UIImage

How to give images in photo library and camera as source to UIImage
/* On button click i want to save image */
myImage = /*What i have to give here to take camera or library images*/
UIImageWriteToSavedPhotosAlbum(myImage, self,
#selector(image:didFinishSavingWithError:contextInfo:), nil);
You need to use the UIImagePickerController object. It will present the modal view that allows either taking a picture or selecting an image from the device library. You should also become familiar with the UIImagePickerControllerDelegate protocol. With these two, it is easy to interact with both the camera and on-device library.