AVFoundation图像捕获 - 捕获用户在UIImage中看到的内容

时间:2014-12-11 16:43:57

标签: ios objective-c uiimage avfoundation

我知道以前曾经问过这个问题,我已经在这里尝试了这个问题的所有答案,我认为有一些基本的东西我不明白所以我的努力​​没有结果所以远。我希望有人能让我觉得自己像个白痴一样挣扎于此并指出我正确的方向。

我尝试做的就是使用AVCaptureSession捕获方形UIImage并将其显示在缩略图图像视图中,看起来与视频图层中的区域完全相同。图像捕获工作正常,但是,当图像添加到我的缩略图图像视图时,图像的顶部和底部被展开以显示照片的区域,这些区域不在用户可见的AvCaptureVideoPreviewLayer中。

以下代码初始化我的会话,一切正常但可能还有我需要更改的内容,只捕获用户可见的部分内容:

-(void)setupFeed
{
    self.session = [[AVCaptureSession alloc] init];

    self.session.sessionPreset = AVCaptureSessionPresetPhoto;
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
    if([self.session canAddInput:deviceInput])
    {
        [self.session addInput:deviceInput];
    }

    self.cameraPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
    [self.cameraPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    CALayer *rootLayer = [[self view] layer];
    [rootLayer setMasksToBounds:YES];
    CGRect frame = self.cameraPreview.frame;
    [self.cameraPreviewLayer setFrame:frame];
    [rootLayer insertSublayer:self.cameraPreviewLayer atIndex:0];

    self.imageOutput = [[AVCaptureStillImageOutput alloc] init];
    NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil];
    [self.imageOutput setOutputSettings:outputSettings];

    [self.session addOutput:self.imageOutput];

    [self.session startRunning];
}

下一段代码是捕获我的图像,这段代码也可以工作,除了:

[self.imageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error)
    {

        if(imageDataSampleBuffer != NULL)
        {
            NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
            self.snappedImage = [UIImage imageWithData:imageData];
            [self.snappedImage crop:self.snappedImageView.layer.frame];
            [self.session stopRunning];;
        }

        dispatch_async(dispatch_get_main_queue(),
        ^{
            [self presentSnappedImageOptions];
        });
    }];
}

-(void)presentSnappedImageOptions
{
    [self.imagePreview setImage: self.snappedImage];
}

...最后是我用来尝试将图像裁剪为与可见视频图层相同的UIImage类别方法:

@implementation UIImage (Crop)

- (UIImage *)crop:(CGRect)rect
{

    rect = CGRectMake(rect.origin.x*self.scale,
                      rect.origin.y*self.scale,
                      rect.size.width*self.scale,
                      rect.size.height*self.scale);

    CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect);
    UIImage *result = [UIImage imageWithCGImage:imageRef
                                          scale:self.scale
                                    orientation:self.imageOrientation];
    CGImageRelease(imageRef);
    return result;
}

@end

任何帮助都会得到很好的回复。

1 个答案:

答案 0 :(得分:1)

我不知道您的视图是如何布局的,但可能是您正在使用的裁剪矩形,“self.snappedImageView.layer.frame”与预览图层显示的捕获图像的区域不对应。

据我所知,预览图层的框架是正方形,正确,因为它的视频重力是纵横填充的,我认为你可以得到图像的最大中心正方形,并将其用作裁剪矩形。

你怎么试试这个

CGSize size = image.size;
CGFloat side = fminf(size.width,size.height); //just the smaller dimension
CGrect croppingRect = CGRectMake((size.width-side)/2.f,(size.height-side)/2.f,side,side);