将AVCaptureVideoPreviewLayer输出裁剪为正方形

mem*_*one 21 objective-c ios avcapturesession

抓取可视屏幕的裁剪UIImage时,我的AVCaptureVideoPreviewLayer方法出现问题.目前它正在工作,但没有输出我需要的正确作物.

我试图输出一个正方形,但它(通过它的外观)似乎给出了完整的高度和压缩图像.

前一图像显示LIVE屏幕,后一图像显示按下捕获按钮后的图像.您可以看到它已垂直更改以适合方形但高度未垂直裁剪.

在此输入图像描述

捕获图像代码

[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) {

    if (imageSampleBuffer != NULL) {

        NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
        [self processImage:[UIImage imageWithData:imageData]];

    }
}];
Run Code Online (Sandbox Code Playgroud)

裁剪代码

- (void) processImage:(UIImage *)image { //process captured image, crop, resize and rotate

        haveImage = YES;

    CGRect deviceScreen = _previewLayer.bounds;
    CGFloat width = deviceScreen.size.width;
    CGFloat height = deviceScreen.size.height;

    NSLog(@"WIDTH %f", width); // Outputing 320
    NSLog(@"HEIGHT %f", height); // Outputting 320

    UIGraphicsBeginImageContext(CGSizeMake(width, width));
    [image drawInRect: CGRectMake(0, 0, width, width)];

    UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    CGRect cropRect = CGRectMake(0, 0, width, width);

    CGImageRef imageRef = CGImageCreateWithImageInRect([smallImage CGImage], cropRect);

    CGImageRelease(imageRef);

    [captureImageGrab setImage:[UIImage imageWithCGImage:imageRef]];

}
Run Code Online (Sandbox Code Playgroud)

Wil*_* Hu 16

你试过设置videoGravity吗?

previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
Run Code Online (Sandbox Code Playgroud)


Ruf*_*fel 7

即使预览图层是方形,请记住生成的静止图像保持其原始大小.

从我看到的,问题出在这里:

UIGraphicsBeginImageContext(CGSizeMake(width, width));
[image drawInRect: CGRectMake(0, 0, width, width)];
Run Code Online (Sandbox Code Playgroud)

您已经使用第一行创建了上下文平方.您仍然需要以原始格式绘制图像,它将被该上下文剪切.在第二行,您强制在正方形中绘制原始图像,从而使其看起来"挤压".

你应该找到合适的图像高度,保持原始比例,同时适合你的"宽度".接下来,您需要在正方形上下文中绘制具有正确大小(保持原始比率)的图像.如果要剪切中心,请更改图形的Y位置.

与此类似的东西:

- (void) processImage:(UIImage *)image {
    UIGraphicsBeginImageContext(CGSizeMake(width, width));
    CGFloat imageHeight = floorf(width / image.width * image.height);
    CGFloat offsetY = floorf((imageHeight - width) / 2.0f);
    [image drawInRect: CGRectMake(0, -offsetY, width, imageHeight)];
    UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    [captureImageGrab setImage:smallImage];
}
Run Code Online (Sandbox Code Playgroud)

应该这样做.