`
miss大为
  • 浏览: 82380 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

如何使用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对象。

#import <AVFoundation/AVFoundation.h>

// 创建并配置一个捕获会话并且启用它
- (void)setupCaptureSession 
{
    NSError *error = nil;

    // 创建session
    AVCaptureSession *session = [[AVCaptureSession alloc] init];

    // 可以配置session以产生解析度较低的视频帧,如果你的处理算法能够应付(这种低解析度)。
    // 我们将选择的设备指定为中等质量。
    session.sessionPreset = AVCaptureSessionPresetMedium;

    // 找到一个合适的AVCaptureDevice
    AVCaptureDevice *device = [AVCaptureDevice
                             defaultDeviceWithMediaType:AVMediaTypeVideo];

    // 用device对象创建一个设备对象input,并将其添加到session
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device 
                                                                    error:&error];
    if (!input) {
        // 处理相应的错误
    }
    [session addInput:input];

    // 创建一个VideoDataOutput对象,将其添加到session
    AVCaptureVideoDataOutput *output = [[[AVCaptureVideoDataOutput alloc] init] autorelease];
    [session addOutput:output];

    // 配置output对象
    dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL);
    [output setSampleBufferDelegate:self queue:queue];
    dispatch_release(queue);

    // 指定像素格式
    output.videoSettings = 
                [NSDictionary dictionaryWithObject:
                    [NSNumber numberWithInt:kCVPixelFormatType_32BGRA] 
                    forKey:(id)kCVPixelBufferPixelFormatTypeKey];


    // 如果你想将视频的帧数指定一个顶值, 例如15ps 
    // 可以设置minFrameDuration(该属性在iOS 5.0中弃用)
    output.minFrameDuration = CMTimeMake(1, 15);

    // 启动session以启动数据流
    [session startRunning];

    // 将session附给实例变量
    [self setSession:session];
}

// 抽样缓存写入时所调用的委托程序
- (void)captureOutput:(AVCaptureOutput *)captureOutput 
         didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
         fromConnection:(AVCaptureConnection *)connection
{ 
    // 通过抽样缓存数据创建一个UIImage对象
    UIImage *image = [self imageFromSampleBuffer:sampleBuffer];

     < 此处添加使用该image对象的代码 >

}

// 通过抽样缓存数据创建一个UIImage对象
- (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer 
{
    // 为媒体数据设置一个CMSampleBuffer的Core Video图像缓存对象
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    // 锁定pixel buffer的基地址
    CVPixelBufferLockBaseAddress(imageBuffer, 0); 

    // 得到pixel buffer的基地址
    void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); 

    // 得到pixel buffer的行字节数
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
    // 得到pixel buffer的宽和高
    size_t width = CVPixelBufferGetWidth(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer); 

    // 创建一个依赖于设备的RGB颜色空间
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

    // 用抽样缓存的数据创建一个位图格式的图形上下文(graphics context)对象
    CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8, 
      bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 
    // 根据这个位图context中的像素数据创建一个Quartz image对象
    CGImageRef quartzImage = CGBitmapContextCreateImage(context); 
    // 解锁pixel buffer
    CVPixelBufferUnlockBaseAddress(imageBuffer,0);

    // 释放context和颜色空间
    CGContextRelease(context); 
    CGColorSpaceRelease(colorSpace);

    // 用Quartz image创建一个UIImage对象image
    UIImage *image = [UIImage imageWithCGImage:quartzImage];

    // 释放Quartz image对象
    CGImageRelease(quartzImage);

    return (image);
}
 
分享到:
评论

相关推荐

    WPF使用Mediafoundation框架捕捉摄像头(源码)

    在本文中,我们将深入探讨如何使用Windows Presentation Foundation (WPF)结合Media Foundation框架来捕捉摄像头。Media Foundation是Microsoft提供的一种高级多媒体处理平台,用于处理音频和视频内容,包括捕获和...

    vb 捕获摄像头图像

    在VB(Visual Basic)编程环境中,捕获摄像头图像是一项常见的任务,这主要涉及到多媒体处理和图形编程。在本文中,我们将深入探讨如何使用VB来实现这一功能,以及相关的技术细节。 首先,VB提供了多种方法来访问和...

    Windows Mobile 摄像头视频流捕获

    在Windows Mobile平台上,摄像头视频流捕获是一项关键的技术,它允许开发者实现各种应用程序,如视频通话、监控系统、影像处理等。本知识点将深入探讨如何在Windows Mobile中捕获和处理来自摄像头的实时视频流。 ...

    vc++Capture摄像头图像捕获与录制程序

    在本文中,我们将深入探讨如何使用VC++进行摄像头图像捕获与录制,主要基于提供的"vc++Capture摄像头图像捕获与录制程序"。这个程序是在Visual Studio 2005环境下编写的,它展示了如何利用VC++的特性来实现视频流的...

    打开并捕获摄像头帧的源码

    在IT领域,尤其是在计算机视觉和实时视频处理中,打开并捕获摄像头帧是常见的操作。这个源码项目提供了一个直接在程序窗口中显示摄像头画面的功能,并允许用户对摄像头的参数进行选择和设置。以下是关于这一主题的...

    sp.rar_USB VC摄像头_usb 视频捕获_usb摄像头_捕获摄像头bmp

    usb 视频捕获_usb摄像头_捕获摄像头bmp”和描述“基于vc 用于捕获USB摄像头视频,保存为BMP”揭示了一个关于使用Visual C++(VC)开发的项目,该项目专注于从USB摄像头捕获视频流并将其保存为BMP图像格式。...

    c#摄像头编程解决跳出捕获源

    在Windows XP中,DirectShow是主要的视频捕获接口,而Windows 7开始引入了Media Foundation,因此在Win7中,系统可能默认使用Media Foundation来处理摄像头输入。如果程序设计时只考虑了DirectShow,那么在Win7上...

    摄像头视频捕获

    摄像头视频捕获是计算机视觉和多媒体技术中的一个重要领域,它涉及到如何从硬件设备,如USB摄像头,捕获实时视频流,并将其保存为可播放的视频文件。在这个过程中,我们通常会利用特定的库或者框架来简化开发工作。...

    易语言摄像头捕获录像源码

    解码是将从摄像头获取的原始格式转换为人眼可识别的图像,编码则是在保存录像时,将图像数据压缩成更小的文件大小,如使用MPEG、H.264等压缩算法。 3. **时间戳管理**:录像文件通常需要记录每个帧的时间信息,以便...

    摄像头实时视频捕获程序

    在IT领域,摄像头实时视频捕获程序是一种常见应用,它能够实时地从计算机的摄像头获取视频流,并进行处理或展示。这种程序广泛应用于各种场景,包括视频会议、监控、在线教学以及娱乐等。下面我们将详细探讨这个主题...

    用VC++实现网络摄像头视频捕获的研究

    AVI Cap支持实时视频流捕获和单帧捕获,还可以选择预览模式或叠加模式来显示视频。预览模式下,视频帧先被传输到系统内存,然后通过GDI函数在捕获窗口显示;叠加模式则直接在硬件级别合并视频信号,无需经过VGA卡,...

    捕获视频为BMP图象

    本项目提供的“捕获视频为BMP图象”是用VC++(Visual C++)编写的源代码,它允许用户通过连接到计算机的视频设备(如摄像头)捕获实时视频帧,并将这些帧保存为BMP(Bitmap)格式的图像文件。下面我们将详细探讨这一...

    易语言后台截取摄像头图像

    这通常需要调用操作系统底层的API接口,比如Windows的DirectShow或Media Foundation框架,来访问摄像头设备并捕获图像。 捕获视频是获取连续的图像帧,而不仅仅是单个静止图像。在易语言中,实现这一功能可能需要...

    AV Foundation 开发秘籍

    3. **视频捕获**:理解如何利用AVCaptureSession进行视频和图像的捕获,包括设置摄像头参数、处理实时预览和录制高质量视频。 4. **多媒体数据流**:探究如何使用AVAsset、AVAssetReader和AVAssetWriter处理多媒体...

    VC6.0 VFW摄像头采集视频图像

    4. **捕获帧**: 使用`AVIStreamReadFormat`或`AVIStreamReadData`函数从视频流中读取帧数据。这些数据通常以位图(BMP)格式存储。 5. **显示或处理图像**: 一旦获取到帧数据,可以将其转换为GDI兼容的位图对象,...

    opencv摄像头捕获视频+C++源码+4个demo+MFC

    总之,这个资源包为C++开发者提供了一个很好的起点,让他们能够利用OpenCV进行摄像头视频捕获和处理。通过学习和理解这些示例代码,开发者可以进一步探索OpenCV的强大功能,比如对象识别、图像拼接、视频编码等,...

    DirectX_capture捕获摄像头源码

    在捕获摄像头视频时,开发者需要设置适当的缓冲区,以存储来自摄像头的每一帧图像数据。 捕获过程通常包括以下步骤: 1. 初始化DirectX环境:创建Direct3D设备,并配置交换链以适应摄像头的视频流。 2. 打开摄像头...

    pb获取摄像头图像实现视频

    5. **捕获帧**:利用`capGrabFrameNoStop`函数捕获摄像头的每一帧图像。 6. **处理图像数据**:捕获到的帧是原始的位图数据,可以使用`capGetImage`获取位图句柄,然后通过PB的图形对象进行进一步处理,如调整亮度...

    MFC+Opencv 摄像头保存为图像和视频

    在本项目中,我们主要探讨如何利用MFC(Microsoft Foundation Classes)框架与OpenCV库来实现摄像头捕获视频并保存为图像和视频的功能。MFC是微软提供的C++类库,用于构建Windows应用程序,而OpenCV则是一个强大的...

    c# 一个功能强大的摄像头捕获程序,可以进行ip对ip的视频通讯,图像效果好

    2. **摄像头捕获**:在C#中,捕获摄像头视频通常涉及Windows Media Foundation (WMF) 或者DirectShow库。WMF是微软提供的多媒体处理框架,能够高效地处理音频和视频流,而DirectShow则是一个更早的多媒体处理API,也...

Global site tag (gtag.js) - Google Analytics