使用avfoundation时 - 裁剪在显示层中表示的捕获图像的可见部分

时间:2014-01-22 07:58:31

标签: ios objective-c avfoundation avcapturesession

我正在使用PBJVision库来捕获图像。

引擎盖下它正在使用AVFoundation。

我将相机设置为使用以下选项

    PBJVision *camera = [[PBJVision alloc] init];
    self.camera = camera;
    self.camera.delegate = self;
    [self.camera setCameraMode:PBJCameraModePhoto];
    [self.camera setCameraDevice:PBJCameraDeviceFront];
    [self.camera setCameraOrientation:PBJCameraOrientationPortrait];
    [self.camera setFocusMode:PBJFocusModeAutoFocus];
    [self.camera setPresentationFrame:self.previewView.frame];
    [self.camera previewLayer].frame = self.previewView.bounds;

    [self.camera previewLayer].videoGravity = AVLayerVideoGravityResizeAspectFill;

    [self.previewView.layer addSublayer:[self.camera previewLayer]];

因为预览图层重力设置为AVLayerVideoGravityResizeAspectFill,所捕获的图像与预览图像不同。

如何根据视频重力裁剪它?

1 个答案:

答案 0 :(得分:2)

根据Erica Sadun的优秀食谱,将以下代码添加到您的视图控制器将允许您执行     UIImage *newImage = [self.applyAspectFillImage: image InRect: self.previewView.bounds];

您可以使用原始照片图像的较小边缘(宽度或高度)来获取最大图像尺寸,以调整目标矩形的大小。

CGFloat scaleW = image.size.width / previewView.bounds.size.width;
CGRect destRect = CGRectMake(0, 0, image.size.width, preview.bounds.size.height * scaleW);
UIImage *newImage = [self.applyAspectFillImage: image InRect: destRect];

代码:

CGRect CGRectCenteredInRect(CGRect rect, CGRect mainRect)
{
    CGFloat xOffset = CGRectGetMidX(mainRect)-CGRectGetMidX(rect);
    CGFloat yOffset = CGRectGetMidY(mainRect)-CGRectGetMidY(rect);
    return CGRectOffset(rect, xOffset, yOffset);
}


// Calculate the destination scale for filling
CGFloat CGAspectScaleFill(CGSize sourceSize, CGRect destRect)
{
    CGSize destSize = destRect.size;
    CGFloat scaleW = destSize.width / sourceSize.width;
    CGFloat scaleH = destSize.height / sourceSize.height;
    return MAX(scaleW, scaleH);
}


CGRect CGRectAspectFillRect(CGSize sourceSize, CGRect destRect)
{
    CGSize destSize = destRect.size;
    CGFloat destScale = CGAspectScaleFill(sourceSize, destRect);
    CGFloat newWidth = sourceSize.width * destScale;
    CGFloat newHeight = sourceSize.height * destScale;
    CGFloat dWidth = ((destSize.width - newWidth) / 2.0f);
    CGFloat dHeight = ((destSize.height - newHeight) / 2.0f);
    CGRect rect = CGRectMake (dWidth, dHeight, newWidth, newHeight);
    return rect;
}



- (UIImage *) applyAspectFillImage: (UIImage *) image InRect: (CGRect) bounds
{
    CGRect destRect;

    UIGraphicsBeginImageContext(bounds.size);
    CGRect rect = CGRectAspectFillRect(image.size, bounds);
    destRect = CGRectCenteredInRect(rect, bounds);

    [image drawInRect: destRect];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;

}