如何使用AV Foundation从摄像头将视频帧捕获为图像

如果译错,感谢指出。

英文原文地址:https://developer.apple.com/library/ios/qa/qa1702/_index.html#//apple_ref/doc/uid/DTS40010192

为了完成实时的捕获,首先初始化一个AVCaputureSession对象用于创建一个捕获会话(session),我们可以使用AVCaptureSession对象将AV输入设备的数据流以另一种形式转换到输出。

然后,我们初始化一个AVCaptureDeviceInput对象,以创建一个输入数据源,该数据源为捕获会话(session)提供视频数据,再调用addInput方法将创建的输入添加到AVCaptureSession对象。

接着初始化一个AVCaptureVideoDataOuput对象,以创建一个输出目标,然后调用addOutput方法将该对象添加到捕获会话中。

AVCaptureVideoDataOutput可用于处理从视频中捕获的未经压缩的帧。一个AVCaptureVideoDataOutput实例能处理许多其他多媒体API能处理的视频帧,你可以通过captureOutput:didOutputSampleBuffer:fromConnection:这个委托方法获取帧,使用setSampleBufferDelegate:queue:设置抽样缓存委托和将应用回调的队列。AVCaptureVideoDataOutputSampleBuffer对象的委托必须采用AVCaptureVideoDataOutputSampleBufferDelegate协议,使用sessionPreset协议来制定输出品质。

我们可以通过调用捕获会话的startRunning方法启动从输入到输出的数据流,通过stopRunning方法来停止数据流。

列表1给出了一个例子。setupCaptureSession创建了一个捕获会话,添加了一个视频输入提供提视频帧,一个输出目标获取捕获的帧,然后启动从输入到输出的数据流。当捕获会话正在运行时,使用captureOut:didOutputSampleBuffer:fromConnection方法将被捕获的视频抽样帧发送给抽样缓存委托,然后每个抽样缓存(CMSampleBufferRef)被转换成imageFromSampleBuffer中的一个UIImage对象。

---------------------------
列表1:使用AV Foundation设置一个捕获设备录制视频并将是视频帧保存为UIImage对象。

C代码 
  1. #import <AVFoundation/AVFoundation.h>  
  2.   
  3. // 创建并配置一个捕获会话并且启用它  
  4. - (void)setupCaptureSession   
  5. {  
  6.     NSError *error = nil;  
  7.   
  8.     // 创建session  
  9.     AVCaptureSession *session = [[AVCaptureSession alloc] init];  
  10.   
  11.     // 可以配置session以产生解析度较低的视频帧,如果你的处理算法能够应付(这种低解析度)。  
  12.     // 我们将选择的设备指定为中等质量。  
  13.     session.sessionPreset = AVCaptureSessionPresetMedium;  
  14.   
  15.     // 找到一个合适的AVCaptureDevice  
  16.     AVCaptureDevice *device = [AVCaptureDevice  
  17.                              defaultDeviceWithMediaType:AVMediaTypeVideo];  
  18.   
  19.     // 用device对象创建一个设备对象input,并将其添加到session  
  20.     AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device   
  21.                                                                     error:&error];  
  22.     if (!input) {  
  23.         // 处理相应的错误  
  24.     }  
  25.     [session addInput:input];  
  26.   
  27.     // 创建一个VideoDataOutput对象,将其添加到session  
  28.     AVCaptureVideoDataOutput *output = [[[AVCaptureVideoDataOutput alloc] init] autorelease];  
  29.     [session addOutput:output];  
  30.   
  31.     // 配置output对象  
  32.     dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL);  
  33.     [output setSampleBufferDelegate:self queue:queue];  
  34.     dispatch_release(queue);  
  35.   
  36.     // 指定像素格式  
  37.     output.videoSettings =   
  38.                 [NSDictionary dictionaryWithObject:  
  39.                     [NSNumber numberWithInt:kCVPixelFormatType_32BGRA]   
  40.                     forKey:(id)kCVPixelBufferPixelFormatTypeKey];  
  41.   
  42.   
  43.     // 如果你想将视频的帧数指定一个顶值, 例如15ps   
  44.     // 可以设置minFrameDuration(该属性在iOS 5.0中弃用)  
  45.     output.minFrameDuration = CMTimeMake(1, 15);  
  46.   
  47.     // 启动session以启动数据流  
  48.     [session startRunning];  
  49.   
  50.     // 将session附给实例变量  
  51.     [self setSession:session];  
  52. }  
  53.   
  54. // 抽样缓存写入时所调用的委托程序  
  55. - (void)captureOutput:(AVCaptureOutput *)captureOutput   
  56.          didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer   
  57.          fromConnection:(AVCaptureConnection *)connection  
  58. {   
  59.     // 通过抽样缓存数据创建一个UIImage对象  
  60.     UIImage *image = [self imageFromSampleBuffer:sampleBuffer];  
  61.   
  62.      < 此处添加使用该image对象的代码 >  
  63.   
  64. }  
  65.   
  66. // 通过抽样缓存数据创建一个UIImage对象  
  67. - (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer   
  68. {  
  69.     // 为媒体数据设置一个CMSampleBuffer的Core Video图像缓存对象  
  70.     CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);   
  71.     // 锁定pixel buffer的基地址  
  72.     CVPixelBufferLockBaseAddress(imageBuffer, 0);   
  73.   
  74.     // 得到pixel buffer的基地址  
  75.     void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);   
  76.   
  77.     // 得到pixel buffer的行字节数  
  78.     size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);   
  79.     // 得到pixel buffer的宽和高  
  80.     size_t width = CVPixelBufferGetWidth(imageBuffer);   
  81.     size_t height = CVPixelBufferGetHeight(imageBuffer);   
  82.   
  83.     // 创建一个依赖于设备的RGB颜色空间  
  84.     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();   
  85.   
  86.     // 用抽样缓存的数据创建一个位图格式的图形上下文(graphics context)对象  
  87.     CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8,   
  88.       bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);   
  89.     // 根据这个位图context中的像素数据创建一个Quartz image对象  
  90.     CGImageRef quartzImage = CGBitmapContextCreateImage(context);   
  91.     // 解锁pixel buffer  
  92.     CVPixelBufferUnlockBaseAddress(imageBuffer,0);  
  93.   
  94.     // 释放context和颜色空间  
  95.     CGContextRelease(context);   
  96.     CGColorSpaceRelease(colorSpace);  
  97.   
  98.     // 用Quartz image创建一个UIImage对象image  
  99.     UIImage *image = [UIImage imageWithCGImage:quartzImage];  
  100.   
  101.     // 释放Quartz image对象  
  102.     CGImageRelease(quartzImage);  
  103.   
  104.     return (image);  
  105. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值