【问题标题】:How to get an exact size frame from image produced by AVCaptureSession?如何从 AVCaptureSession 生成的图像中获取精确大小的帧?
【发布时间】:2017-09-06 02:45:35
【问题描述】:

我正在开发一个应用程序,该应用程序捕获 AVCaptureSession 内部的特定视图,如上图所示。

我正在使用AVCaptureStillImageOutputAVCaptureSession 中捕获图像。问题是我得到了一个特定大小的图像,即 ({2448, 3264})。我的解决方案是将此图像转换为与我的背景视图相同的框架,以便具有相同的坐标和框架。

使用 imageWithImage,我使用了与 captureView 相同的框架,一切正常。 resizedImage 最终是 {768, 1024},它与 AVCaptureSession 的大小相同。

从现在开始,基于这个坐标,我尝试使用 CGImageCreateWithImageInRect 基于 captureView 的框架(即绿色视图)裁剪图像。

我得到的输出图像是关闭的。我的问题是有没有比CGImageCreateWithImageInRect 更好的方法来从我从 AVCaptureSession 返回的图像中捕获我想要的确切视图?有没有更好的方法来做我想要实现的?任何帮助将不胜感激。提前致谢!

  AVCaptureConnection *videoConnection = nil;
    for (AVCaptureConnection *connection in stillImageOutput.connections) {
        for (AVCaptureInputPort *port in [connection inputPorts]) {
            if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
                videoConnection = connection;

                //Handle orientation for video

                if(videoConnection.supportsVideoOrientation)
                {
                    if(captureVideoPreviewLayer.connection.videoOrientation == UIInterfaceOrientationLandscapeLeft ){
                        videoConnection.videoOrientation = AVCaptureVideoOrientationLandscapeLeft;
                    }
                    if(captureVideoPreviewLayer.connection.videoOrientation == UIInterfaceOrientationLandscapeRight ){
                        videoConnection.videoOrientation = AVCaptureVideoOrientationLandscapeRight;
                    }
                    if(captureVideoPreviewLayer.connection.videoOrientation == UIInterfaceOrientationPortrait ){
                        videoConnection.videoOrientation = AVCaptureVideoOrientationPortrait;
                    }
                }
                break;
            }
        }
        if (videoConnection) { break; }
    }

    NSLog(@"about to request a capture from: %@", stillImageOutput);
    __weak typeof(self) weakSelf = self;
    [stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) {

        NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
        UIImage *image = [[UIImage alloc] initWithData:imageData];
        UIImage *resizedImage = [weakSelf imageWithImage:image scaledToSize:outputImageView.frame.size];

        //Image view to test screenshot of AVCaptureSession
        outputImageView.image = resizedImage;

        //Screenshot of captureView frame (green view)
        CGRect captureFrame = captureView.frame;

        CGImageRef cropRef = CGImageCreateWithImageInRect(resizedImage.CGImage, captureFrame);
        UIImage* cropImage = [UIImage imageWithCGImage:cropRef];

// Image view to test cropped image
        sampleImageView.image = cropImage;

        //Hide Indicator
        [weakSelf hideActivityView];

    }];

- (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
    //UIGraphicsBeginImageContext(newSize);
    // In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
    // Pass 1.0 to force exact pixel size.
    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

用于捕获图像的方法。

【问题讨论】:

  • 你试过videoGravityAVCaptureVideoPreviewLayer
  • @MikeAlter 是的,它当前设置为 AVLayerVideoGravityResizeAspect。更改视频重力不会改变我使用 AVCaptureStillImageOutput 从 AVCaptureSession 返回的图像大小。我希望能够将 AVCaptureStillImageOutput 的框架设置为特定的框架。这行代码“captureVideoPreviewLayer.frame = cameraView.frame;”设置 AVCaptureVideoPreviewLayer 没有帮助。

标签: ios objective-c avcapturesession


【解决方案1】:

正如 cmets 所说,我通过将像素缩放比例更改为 1.0 解决了我的问题。

- (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
    //UIGraphicsBeginImageContext(newSize);
    // In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
    // Pass 1.0 to force exact pixel size.
    UIGraphicsBeginImageContextWithOptions(newSize, NO, 1.0);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多