将AVCaptureVideoPreviewLayer输出裁剪为正方形 [英] Cropping AVCaptureVideoPreviewLayer output to a square

查看:261
本文介绍了将AVCaptureVideoPreviewLayer输出裁剪为正方形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am having issues with my AVCaptureVideoPreviewLayer method when grabbing a cropped UIImage of the viewable screen. Currently it is working but not outputting the correct crop that I require.

我正在尝试输出一个正方形但它(看起来很像)似乎给了全高并压缩图像。

I am trying to output a square but it (by the looks of it) seems to be giving the full height and compressing the image.

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

The before image shows the LIVE screen and the after image shows the image once the capture button has been pressed. You can see that it has been changed vertically to fit the square but the height hasn't been cropped vertically.

捕获图像代码

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

    if (imageSampleBuffer != NULL) {

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

    }
}];

裁剪代码

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

}


推荐答案

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

Even if the preview layer is square, keep in mind that the generated still image keeps its original size.

从我看到的,问题在于:

From what I see, the problem is here:

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

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

You already made your context square with the first line. You still need to draw your image in its original format, it will be clipped by that context. On the second line, you are forcing the drawing of the original image in a square, thus making it look "squeezed".

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

You should find the right image height that keeps the original ratio while fitting your "width". Next, you will want to draw that image with the correct size (keeping the original ratio) in your square context. If you want to clip the center, change your Y position of the drawing.

类似于此内容:

- (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];
}

应该这样做。

这篇关于将AVCaptureVideoPreviewLayer输出裁剪为正方形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆