Is it possible to take a snapshot of combined views including the camera?

193 views Asked by At

My app has a button that should take a screenshot of whatever is on the screen by calling "takeSnapShot" (see code below). I have two views and one of them is a picker view that I use for the camera, so in the screen I see the image coming from the camera and next to it another view with images.

The thing is that I capture the screen but it doesn't capture the image coming from the camera.

Also, I think I render the view.layer but the debugger keeps saying>

"Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates."

Any ideas? Thanks!

This is the code:

#import "ViewController.h"

@interface ViewController ()
@end

@implementation ViewController

UIImage *capturaPantalla;


-(void)takeSnapShot:(id)sender{

   UIGraphicsBeginImageContext(picker.view.window.bounds.size);
   [picker.view.layer renderInContext:UIGraphicsGetCurrentContext()];
   capturaPantalla = UIGraphicsGetImageFromCurrentImageContext();
   UIGraphicsEndImageContext();

   UIImageWriteToSavedPhotosAlbum(capturaPantalla,nil,nil,nil);

}
1

There are 1 answers

3
Alex Cheng On BEST ANSWER

I did the similar function before, and used AVCaptureSession to make it.

 // 1. Create the AVCaptureSession
    AVCaptureSession *session = [[AVCaptureSession alloc] init];
    [self setSession:session];

 // 2. Setup the preview view
    [[self previewView] setSession:session];

 // 3. Check for device authorization
    [self checkDeviceAuthorizationStatus];

    dispatch_queue_t sessionQueue = dispatch_queue_create("session queue", DISPATCH_QUEUE_SERIAL);
    [self setSessionQueue:sessionQueue];

============================================ My countdown snapshot function:

- (void) takePhoto
{
    [timer1 invalidate];
    dispatch_async([self sessionQueue], ^{
        // 4. Update the orientation on the still image output video connection before capturing.
        [[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:[[(AVCaptureVideoPreviewLayer *)[[self previewView] layer] connection] videoOrientation]];

        // 5. Flash set to Auto for Still Capture
        [iSKITACamViewController setFlashMode:flashMode forDevice:[[self videoDeviceInput] device]];

        AVCaptureConnection *stillImageConnection = [[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo];

        CGFloat maxScale = stillImageConnection.videoMaxScaleAndCropFactor;
        if (effectiveScale > 1.0f && effectiveScale < maxScale)
        {
            stillImageConnection.videoScaleAndCropFactor = effectiveScale;;
        }

        [self playSound];
        // 6.Capture a still image.
        [[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {

            if (imageDataSampleBuffer)
            {
                NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
                UIImage *image = [[UIImage alloc] initWithData:imageData];
                if(iPhone5 && [self.modeLabel.text isEqualToString:@"PhotoMode"]) {
                    UIImage *image1 = [image crop:CGRectMake(0, 0, image.size.width, image.size.height)];
                    [[[ALAssetsLibrary alloc] init] writeImageToSavedPhotosAlbum:[image1 CGImage] orientation:(ALAssetOrientation)[image1 imageOrientation] completionBlock:nil];
                } else {
                    [[[ALAssetsLibrary alloc] init] writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)[image imageOrientation] completionBlock:nil];

                }
                self.priveImageView.image = image;
            }
        }];
    });
}