Iphone 是否可以在图形上下文中呈现AVCaptureVideoPreviewLayer?
这似乎是一项简单的任务,但却让我发疯是否可以将包含AVCaptureVideoPreviewLayer的UIView作为子层转换为要保存的图像?我想创建一个增强现实叠加,并使用一个按钮将图片保存到相机卷。按住power按钮+home(主页)键可将屏幕截图捕获到相机卷上,这意味着我的所有捕获逻辑都在工作,并且任务是可能的。但我似乎无法使它以编程方式工作 我正在使用AVCaptureVideoPreviewLayer拍摄相机图像的实时预览。我所有渲染图像的尝试都失败:Iphone 是否可以在图形上下文中呈现AVCaptureVideoPreviewLayer?,iphone,objective-c,uiview,avfoundation,Iphone,Objective C,Uiview,Avfoundation,这似乎是一项简单的任务,但却让我发疯是否可以将包含AVCaptureVideoPreviewLayer的UIView作为子层转换为要保存的图像?我想创建一个增强现实叠加,并使用一个按钮将图片保存到相机卷。按住power按钮+home(主页)键可将屏幕截图捕获到相机卷上,这意味着我的所有捕获逻辑都在工作,并且任务是可能的。但我似乎无法使它以编程方式工作 我正在使用AVCaptureVideoPreviewLayer拍摄相机图像的实时预览。我所有渲染图像的尝试都失败: previewLayer
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的安全问题。这是真的吗
我只是想说清楚:我不想为相机保存图像。我想保存叠加在另一个图像上的透明预览层,从而创建透明度。但由于某些原因,我无法使其工作 我建议你试试GPU图像 它使用openGL,所以速度相当快。它可以处理来自相机的图片,并为其添加过滤器(有很多),包括边缘检测、运动检测等 它类似于OpenCV,但根据我自己的经验,GPU图像更容易与您的项目连接,并且语言是objective-c
如果您决定将box2d用于物理,可能会出现问题-is也使用openGl,您需要花费一些时间,直到这两个框架停止斗争)我喜欢@Roma关于使用GPU图像的建议-好主意。然而,如果你想要一个纯粹的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中李>
- 将覆盖添加到顶部作为子视图李>
+ (UIImage*)imageWithView:(UIView*)view
{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, [UIScreen mainScreen].scale);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage* img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
我猜OP和我正在尝试的是,使用avcapturevideopreviewlayer获取实时视频提要,并尝试添加缩放图像。我正试图在基于人脸检测的实时视频提要上添加一个缩放图像,保存的屏幕截图只是覆盖层的截图,而不是avcapturevideopreviewlayer。在GPU图像中,有人在层上添加过滤器,所以我很确定有办法只保存当前层(GPU图像中有方法从帧中生成UIImage)如果你想得到屏幕上显示的内容,有一种方法可以通过编程来制作屏幕截图。我现在记不起来了,但我在stackoverflow(Roma)上看到过,非常感谢你的回答。虽然我没有使用GPUImage,但我肯定会很快使用它。谢谢你把它作为另一个选择。我想这就是我想要的。我会试着让它运行,让你知道它是如何运行的。谢谢你的快速回答!是否对image=[image rotate:UIImageOrientationRight];(图像旋转:UIImageOrientationRight];)使用uiimage扩展名?是的,该步骤是可选的。但是,让我给你代码。这是旋转实用程序:Jasper,非常感谢,你的回答和评论对它的工作非常有帮助!