我正在尝试模拟在默认相机应用程序中看到的动画,其中相机取景器的快照被动画到应用程序显示的角落。
拥有解决此问题的关键的 AVCaptureVideoPreviewLayer 对象对这些要求不是很开放:尝试使用 ..
- (id)initWithLayer:(id)layer
.. 返回一个空层,没有图像快照,所以很明显这里有一些更深层次的魔法。
非常欢迎您提供线索/嘘声。
M。
我正在尝试模拟在默认相机应用程序中看到的动画,其中相机取景器的快照被动画到应用程序显示的角落。
拥有解决此问题的关键的 AVCaptureVideoPreviewLayer 对象对这些要求不是很开放:尝试使用 ..
- (id)initWithLayer:(id)layer
.. 返回一个空层,没有图像快照,所以很明显这里有一些更深层次的魔法。
非常欢迎您提供线索/嘘声。
M。
从稍微不同的角度面对同样的困境。
以下是可能的解决方案,没有一个是太棒的 IMO:
您可以将AVCaptureStillImageOutput和AVCaptureVideoDataOutput添加到AVCaptureSession中。当您将sessionPreset设置为AVCaptureSessionPresetHigh时,您将开始通过 API 获取帧,当您切换到AVCaptureSessionPresetPhoto时,您可以拍摄真实图像。因此,在拍照之前,您可以切换到视频,获取帧,然后返回相机。主要需要注意的是,相机在摄像机和图片相机之间切换需要“很长时间”(几秒钟)。
另一种选择是仅使用相机输出(AVCaptureStillImageOutput),并使用UIGetScreenImage来获取手机的屏幕截图。然后,您可以裁剪控件并仅保留图像。如果您在图像上显示 UI 控件,这会变得复杂。此外,根据这篇文章,Apple 开始拒绝使用此功能的应用程序(它总是有问题)。
除了这些,我还尝试使用AVCaptureVideoPreviewLayer。有这篇文章将 UIView 或 CALayer 保存到 UIImage。但这一切都会产生清晰或白色的图像。我尝试访问该层、视图层、超层、presentationLayer、modelLayer,但无济于事。我猜AVCaptureVideoPreviewLayer中的数据是非常内部的,并不是常规层基础设施的一部分。
希望这会有所帮助,奥德。
我认为您应该AVCaptureVideoDataOutput
在当前会话中添加一个:
AVCaptureVideoDataOutput *videoOutput = [[AVCaptureVideoDataOutput alloc] init];
videoOutput.videoSettings = @{ (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA) };
[session addOutput:videoOutput];
dispatch_queue_t queue = dispatch_queue_create("MyQueue", NULL);
[videoOutput setSampleBufferDelegate:self queue:queue];
dispatch_release(queue);
然后,实现下面的委托方法来获取你的图像快照:
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
UIImage *image = [self imageFromSampleBuffer:sampleBuffer];
// Add your code here that uses the image.
dispatch_async(dispatch_get_main_queue(), ^{
_imageView.image = image;
});
}
这将消耗内存并降低应用程序的性能。为了改进,您还可以优化您AVCaptureVideoDataOutput
的:
videoOutput.minFrameDuration = CMTimeMake(1, 15);
您也可以使用alwaysDiscardsLateVideoFrames
.
有 2 种方法来抓取预览帧.. AVCaptureVideoDataOutput & AVCaptureStillImageOutput :)
您的捕获会话是否设置为抓取视频帧,然后使用所选帧中的 cgimage 制作图层。如果它是为静止图像设置的,请等到获取静止图像并从该 cgimage 的缩小版本制作图层。如果您的会话还没有输出,我认为您必须添加一个。
从 iOS 7 开始,您可以使用UIView::snapshotViewAfterScreenUpdates对包装 AVCaptureVideoPreviewLayer 的 UIView 进行快照。这与 不同UIGetScreenImage
,这将使您的应用程序被拒绝。
UIView *snapshot = [self.containerView snapshotViewAfterScreenUpdates:YES];
回想一下将视图转换为图像的老式方法。出于某种原因,它适用于除相机预览之外的所有内容:
UIGraphicsBeginImageContextWithOptions(self.containerView.bounds.size, NO, [UIScreen mainScreen].scale);
[self.containerView drawViewHierarchyInRect:self.containerView.bounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();