2

I am using AVCam made by apple for my custom camera view. Honestly it is not to simple to understand what's going on in the class AVCamViewController if you see it at first time.

Right now I am interested how they set frame of captured image. I tried to found where some fames setters or something like this, but I have not found any.

I searched in Google and found answer here AVCam not in fullscreen

But when I implemented that solution I just realised that it just made live camera preview layer with the same size as my view, but when app saves image in the method - (IBAction)snapStillImage:(id)sender in the gallery images still was with 2 stripes from left and right.

My question is how can I remove this stripes or in which line in source code apple set this stuff?

Also as additional sub-question how can I set type create just photo, because the app requests me "Microphone settings" and I don't need it just need make a photo and that's it.

This code from apple sources will save image to the photo library.

- (IBAction)snapStillImage:(id)sender
{
    dispatch_async([self sessionQueue], ^{
        // Update the orientation on the still image output video connection before capturing.
        [[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:[[(AVCaptureVideoPreviewLayer *)[[self previewView] layer] connection] videoOrientation]];

        // Flash set to Auto for Still Capture
        [AVCamViewController setFlashMode:AVCaptureFlashModeAuto forDevice:[[self videoDeviceInput] device]];

        // 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];

                UIImage *proccessingImage = [SAPAdjustImageHelper adjustImage:image];

                NSNumber *email_id = [SAPCoreDataEmailHelper currentEmailId];

                [SAPFileManagerHelper addImage:proccessingImage toFolderWithEmailId:email_id];
            }
        }];
    });
}
Community
  • 1
  • 1
Matrosov Oleksandr
  • 25,505
  • 44
  • 151
  • 277
  • please, add code or screenshot preview... – hmdeep Sep 05 '14 at 11:49
  • according to my experience,it's work fine in iPhone5 but problem is only in iPhone 4 ,Right??? – hmdeep Sep 05 '14 at 11:56
  • you can download code here https://developer.apple.com/library/ios/samplecode/AVCam/Introduction/Intro.html as I described above. I have not modified nothing – Matrosov Oleksandr Sep 05 '14 at 11:57
  • did you test it on iPhone 5 and 4? – hmdeep Sep 05 '14 at 11:59
  • @hmdeep I test it on iPad I don't know. It works good but has stripes, so it means there are 2 black fields and when I save captured image pressing still button it has 2 black stiles as in the cinema )) I don't why they did not use full frame as it provided by camera but reduce frame to another size – Matrosov Oleksandr Sep 05 '14 at 12:01
  • once i had save problem,it's works fine in iPhone5 but in iPhone 4 it's get erred image as you mention here.i solve my problem with take camera Preview layer as 568 height and crop upper 320 X 480 from captured image and also there is no stripes with 320 X 568 capture size.. – hmdeep Sep 05 '14 at 12:06
  • And for iPad set "previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill" with same code – hmdeep Sep 05 '14 at 12:11
  • @hmdeep I set it into the - (void)setSession:(AVCaptureSession *)session method in AVCamPreviewView.m but it just resize live preview layer, when I tap still image button in the gallery same result with stripes on the boards, but on the screen in app there are not stripes, because of this method. Maybe I should add it some where else? – Matrosov Oleksandr Sep 05 '14 at 12:22

2 Answers2

4

Are you setting the session preset?

You can use your session with the session preset set in AVCaptureSessionPresetPhoto.

For the another subquestion: You need to add only the AVCaptureStillImageOutput output.

How to set the session Preset?

[session setSessionPreset:AVCaptureSessionPresetPhoto];

How to configure the session to use only StillImageOutput to take photos and ?

- (void)viewDidLoad
{
    [super viewDidLoad];

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

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

    // Setup the session Preset          
    [session setSessionPreset:AVCaptureSessionPresetPhoto];

    // Check for device authorization
    [self checkDeviceAuthorizationStatus];

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

    dispatch_async(sessionQueue, ^{
        //[self setBackgroundRecordingID:UIBackgroundTaskInvalid];

        NSError *error = nil;

        AVCaptureDevice *videoDevice = [AVCamViewController deviceWithMediaType:AVMediaTypeVideo preferringPosition:AVCaptureDevicePositionBack];
        AVCaptureDeviceInput *videoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];

        if (error)
        {
            NSLog(@"%@", error);
        }

        if ([session canAddInput:videoDeviceInput])
        {
            [session addInput:videoDeviceInput];
            [self setVideoDeviceInput:videoDeviceInput];

            dispatch_async(dispatch_get_main_queue(), ^{
                // Why are we dispatching this to the main queue?
                // Because AVCaptureVideoPreviewLayer is the backing layer for AVCamPreviewView and UIView can only be manipulated on main thread.
                // Note: As an exception to the above rule, it is not necessary to serialize video orientation changes on the AVCaptureVideoPreviewLayer’s connection with other session manipulation.

                [[(AVCaptureVideoPreviewLayer *)[[self previewView] layer] connection] setVideoOrientation:(AVCaptureVideoOrientation)[self interfaceOrientation]];
            });
        }

AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
        if ([session canAddOutput:stillImageOutput])
        {
            [stillImageOutput setOutputSettings:@{AVVideoCodecKey : AVVideoCodecJPEG}];
            [session addOutput:stillImageOutput];
            [self setStillImageOutput:stillImageOutput];
        }
    });
}
dcorbatta
  • 1,893
  • 19
  • 15
  • ok I will check your answer today thank a lot) I will mark it as accepted question just let me test it) – Matrosov Oleksandr Sep 08 '14 at 20:24
  • by some reason app crashes after I take 2 or one photo – Matrosov Oleksandr Sep 08 '14 at 21:39
  • so I just added a line [session setSessionPreset:AVCaptureSessionPresetPhoto]; and it works perfect but when app starts invocation snapStillImage app crashes. delete this line app takes photos but has black stripes – Matrosov Oleksandr Sep 08 '14 at 21:50
  • I just alos found http://stackoverflow.com/questions/19179070/captured-photo-is-stretched-with-avcapturesession-sessionpreset-avcapturesessi seems it also resolve issue with crash – Matrosov Oleksandr Sep 08 '14 at 22:11
  • oh, ok seems with your combination answered here http://stackoverflow.com/questions/20497575/avcam-not-in-fullscreen it works perfect. – Matrosov Oleksandr Sep 08 '14 at 22:50
  • 1
    Sorry for the delay. Yes, you need to configure the preview layer also. :) I don't know why the code cause a crash. Maybe there is a bug in my snipped code. – dcorbatta Sep 09 '14 at 13:53
  • it does not cause a crash if i use code to setup layer in avcam preview class as you answered in another question. – Matrosov Oleksandr Sep 10 '14 at 19:51
  • Mmm. What device are you using? – dcorbatta Sep 11 '14 at 03:18
  • i use iPad mini, but it everything work perfect right now. as I said I just added code from both your answers. and it works thanks – Matrosov Oleksandr Sep 11 '14 at 16:28
  • Yep, but I can't reproduce the error without set the video gravity and bounds of the preview layer. I don't know what is the relation between this setting and the another. :( – dcorbatta Sep 11 '14 at 17:28
  • first file http://codepaste.net/tyqiuj and second file http://codepaste.net/e1jog8 If I don't add these to lines ((AVPlayerLayer *)[self layer]).videoGravity = AVLayerVideoGravityResizeAspectFill; ((AVPlayerLayer *)[self layer]).bounds = ((AVPlayerLayer *)[self layer]).bounds; it cause a crash by some reason, but if I add these line it works perfect. – Matrosov Oleksandr Sep 16 '14 at 19:39
0

The blacks fields are needed to keep the aspect ratio, if want to avoid them you should change the videoGravity in the AVCaptureVideoPreviewLayer, or in the contentMode of the UIImageView displaying the captured image.
This is an expected behavior, don't understand your concern.

Andrea
  • 26,120
  • 10
  • 85
  • 131
  • ok when I use UIIMagePickerController I got great! image, without any stripes. This is my concern, but when run apple sources I got half image instead of 100 size. this is a concern. Video gravity is ok but only for preview. The saved image in gallery will be have half size of iPad screen in any case. I don't use any UIImageView. – Matrosov Oleksandr Sep 05 '14 at 12:55
  • I have added code that apple use for save image to library, is there any UIImageView in AVCam example provided by apple. About which contentMode have you said? – Matrosov Oleksandr Sep 05 '14 at 12:57
  • I also found this link http://stackoverflow.com/questions/20497575/avcam-not-in-fullscreen but as I said it just make full screen for live recording component. After save image to the library using this method - (IBAction)snapStillImage:(id)sender image will have half size of the iPad screen size. – Matrosov Oleksandr Sep 05 '14 at 12:59
  • Image captured using AVCaptureConnection can have different resolution based on the quality that has been set to capture session. I suggest you to export the images and check the resolution of the images. I can tell you for sure that the normal API doesn't draw the back stripes – Andrea Sep 05 '14 at 14:26
  • Ok let's skip stripes. I just one to say when I use UIImagePicker I have full screen image in photo library on iPad. Or If use camera app on iPad that is internal app. The photo in all of these cases is biggest then that I got via AVCam on iPad. And there is no UIImageView at all in this code, You can download it to make sure. – Matrosov Oleksandr Sep 05 '14 at 14:50
  • so have then change quality of image in AVCam to have the same resolution in AVCam as I have when take a picture using camera app on iPad – Matrosov Oleksandr Sep 05 '14 at 14:51