iphone - 是否可以在图形上下文中渲染 AVCaptureVideoPreviewLayer?

标签 iphone objective-c uiview avfoundation

这似乎是一项简单的任务,但却让我抓狂。 是否可以将包含 AVCaptureVideoPreviewLayer 作为子层的 UIView 转换为要保存的图像?我想创建一个增强现实叠加层并使用一个按钮将图片保存到相机胶卷。按住电源按钮 + 主页键将屏幕截图捕获到相机胶卷,这意味着我的所有捕获逻辑都在工作,并且任务是可能的。但我似乎无法使其以编程方式工作。

我正在使用 AVCaptureVideoPreviewLayer 捕获相机图像的实时预览。我所有渲染图像的尝试都失败了:

  previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:captureSession];
//start the session, etc...


//this saves a white screen
- (IBAction)saveOverlay:(id)sender {
    NSLog(@"saveOverlay");

    UIGraphicsBeginImageContext(appDelegate.window.bounds.size);
        UIGraphicsBeginImageContext(scrollView.frame.size);

    [previewLayer.presentationLayer renderInContext:UIGraphicsGetCurrentContext()];


//    [appDelegate.window.layer renderInContext:UIGraphicsGetCurrentContext()];

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

    UIImageWriteToSavedPhotosAlbum(screenshot, self, 
                                   @selector(image:didFinishSavingWithError:contextInfo:), nil);
}

//这会渲染所有内容,除了预览层,它是空白的。

[appDelegate.window.layer renderInContext:UIGraphicsGetCurrentContext()];

我在某处读到这可能是由于 iPhone 的安全问题。这是真的吗?

明确一点:我不想为相机保存图像。我想保存叠加在另一个图像上的透明预览层,从而创建透明度。但由于某种原因我无法使其工作。

最佳答案

我喜欢@Roma 关于使用 GPU Image 的建议 - 好主意。 . . .但是,如果您想要纯 CocoaTouch 方法,请执行以下操作:

实现 AVCaptureVideoDataOutputSampleBufferDelegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
    // Create a UIImage+Orientation from the sample buffer data
    if (_captureFrame)
    {
        [captureSession stopRunning];

        _captureFrame = NO;
        UIImage *image = [ImageTools imageFromSampleBuffer:sampleBuffer];
        image = [image rotate:UIImageOrientationRight];

        _frameCaptured = YES;

        if (delegate != nil)
        {
            [delegate cameraPictureTaken:image];
        }
    }
}

抓取如下:

+ (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer 
{
    // Get a CMSampleBuffer's Core Video image buffer for the media data
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    // Lock the base address of the pixel buffer
    CVPixelBufferLockBaseAddress(imageBuffer, 0); 

    // Get the number of bytes per row for the pixel buffer
    void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); 

    // Get the number of bytes per row for the pixel buffer
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
    // Get the pixel buffer width and height
    size_t width = CVPixelBufferGetWidth(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer); 

    // Create a device-dependent RGB color space
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

    // Create a bitmap graphics context with the sample buffer data
    CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8, 
                                             bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 
    // Create a Quartz image from the pixel data in the bitmap graphics context
    CGImageRef quartzImage = CGBitmapContextCreateImage(context); 
    // Unlock the pixel buffer
    CVPixelBufferUnlockBaseAddress(imageBuffer,0);

    // Free up the context and color space
    CGContextRelease(context); 
    CGColorSpaceRelease(colorSpace);

    // Create an image object from the Quartz image
    UIImage *image = [UIImage imageWithCGImage:quartzImage];

    // Release the Quartz image
    CGImageRelease(quartzImage);

    return (image);
}

将 UIImage 与叠加层混合

  • 现在您有了 UIImage,将它添加到新的 UIView。
  • 将叠加层添加为 subview 。

捕获新的 UIView

+ (UIImage*)imageWithView:(UIView*)view
{
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, [UIScreen    mainScreen].scale);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage* img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}

关于iphone - 是否可以在图形上下文中渲染 AVCaptureVideoPreviewLayer?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9012397/

相关文章:

iphone - 如何从苹果开发者成员(member)帐户禁用测试设备上的 iPhone 应用程序

ios - 将自定义字体添加到 XIB 中的字体列表

objective-c - 为什么++ 运算符将整数增加 4 而不是增加 1?

iphone - 来自 AppDelegate 的共享 ADBannerView - 如何从代表处获取广告

iphone - phonegap 是否支持离线存储缓存 list ?

ios - UIKeyboardWillShowNotification 错误地更改了 UIWebView 的框架

ios - 释放 iOS 中 ARC 下的 NSMutableDictionary 内存

ios - 更改 subview 的高度后调整 super View 的大小 - 没有自动布局

ios - 在旋转时调整 UIViewController 内的全屏 View 大小?

uiview - 在 UIView 布局中,什么是 "update cycle"?