通过AVFoundation框架获取摄像头数据
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                通过AVFoundation框架获取摄像头数据
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                
                            
                            
                            一、概述 
 
從iOS4開始,AVFoundation框架增加了幾個類,AVCaptureDevice、AVCaptureSession等,可以獲取攝像頭的數據,而不會彈出類似于ImagePicker一樣的界面,我們可以將數據轉為一張張的圖片,然后我們可以即時顯示在視圖上,也可以使用FFMPEG或者其它的視頻編碼工具,來合成視頻。
二、步驟
第一步:創建AVCaptureSession,添加輸入,輸出源
#import <AVFoundation/AVFoundation.h>
//創建并配置一個攝像會話,并啟動。 - (void)setupCaptureSession { ? ? NSError *error = nil;
? ? //創建會話 ? ? AVCaptureSession *session = [[AVCaptureSession alloc] init];
? ? //設置視頻質量 ? ? session.sessionPreset = AVCaptureSessionPresetMedium;
? ? //獲取合適的AVCaptureDevice ? ? AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
? ? //創建設備輸入流,并增加到會話。 ? ? AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? error:&error]; ? ? if (!input) { ? ? ? ? //處理錯誤 ? ? } ? ? [session addInput:input];
? ? //創建一個視頻輸出流,并增加到會話。 ? ? AVCaptureVideoDataOutput *output = [[[AVCaptureVideoDataOutput alloc] init] autorelease]; ? ? [session addOutput: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];
? ? //設置FPS ? ? output.minFrameDuration = CMTimeMake(1, 15);
? ? //啟動會話 ? ? [session startRunning];
? ? //將會話與當前控制器關聯 ? ? [self setSession:session]; }
第二步:實現AVCaptureVideoDataOutputSampleBufferDelegate協議方法 ? //當采樣數據被寫入緩沖區時調用 - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer ? ? ? ? ?fromConnection:(AVCaptureConnection *)connection { ? ? //抽取采樣數據,合成UIImage對象 ? ? UIImage *image = [self imageFromSampleBuffer:sampleBuffer]; ? ? //后續自定義處理 ? ? xxxxxxxx }
//抽取采樣數據,合成UIImage對象 - (UIImage *)imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer { ? ? CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); ? ?? ? ? //鎖定像素緩沖區的起始地址 ? ? CVPixelBufferLockBaseAddress(imageBuffer,0);
? ? //獲取每行像素的字節數 ? ? size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); ? ?? ? ? //獲取像素緩沖區的寬度和高度 ? ? size_t width = CVPixelBufferGetWidth(imageBuffer); ? ? size_t height = CVPixelBufferGetHeight(imageBuffer);
? ? //創建基于設備的RGB顏色空間 ? ? CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); ? ? if (!colorSpace) ? ? { ? ? ? ? NSLog(@"CGColorSpaceCreateDeviceRGB failure"); ? ? ? ? return nil; ? ? }
? ? //獲取像素緩沖區的起始地址 ? ? void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); ? ?? ? ? //獲取像素緩沖區的數據大小 ? ? size_t bufferSize = CVPixelBufferGetDataSize(imageBuffer);
? ? //使用提供的數據創建CGDataProviderRef ? ? CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, baseAddress, bufferSize,NULL); ? ?? ? ? //通過CGDataProviderRef,創建CGImageRef ? ? CGImageRef cgImage = ? ? ? ? CGImageCreate(width, ? ? ? ? ? ? ? ? ? ? ? ? height, ? ? ? ? ? ? ? ? ? ? ? ? 8, ? ? ? ? ? ? ? ? ? ? ? ? 32, ? ? ? ? ? ? ? ? ? ? ? ? bytesPerRow, ? ? ? ? ? ? ? ? ? ? ? ? colorSpace, ? ? ? ? ? ? ? ? ? ? ? ? kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little, ? ? ? ? ? ? ? ? ? ? ? ? provider, ? ? ? ? ? ? ? ? ? ? ? ? NULL, ? ? ? ? ? ? ? ? ? ? ? ? true, ? ? ? ? ? ? ? ? ? ? ? ? kCGRenderingIntentDefault); ? ? CGDataProviderRelease(provider); ? ? CGColorSpaceRelease(colorSpace);
? ? //創建UIImage ? ? UIImage *image = [UIImage imageWithCGImage:cgImage]; ? ? CGImageRelease(cgImage);
? ? //解鎖像素緩沖區起始地址 ? ? CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
? ? return image; }
                        
                        
                        從iOS4開始,AVFoundation框架增加了幾個類,AVCaptureDevice、AVCaptureSession等,可以獲取攝像頭的數據,而不會彈出類似于ImagePicker一樣的界面,我們可以將數據轉為一張張的圖片,然后我們可以即時顯示在視圖上,也可以使用FFMPEG或者其它的視頻編碼工具,來合成視頻。
二、步驟
第一步:創建AVCaptureSession,添加輸入,輸出源
#import <AVFoundation/AVFoundation.h>
//創建并配置一個攝像會話,并啟動。 - (void)setupCaptureSession { ? ? NSError *error = nil;
? ? //創建會話 ? ? AVCaptureSession *session = [[AVCaptureSession alloc] init];
? ? //設置視頻質量 ? ? session.sessionPreset = AVCaptureSessionPresetMedium;
? ? //獲取合適的AVCaptureDevice ? ? AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
? ? //創建設備輸入流,并增加到會話。 ? ? AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? error:&error]; ? ? if (!input) { ? ? ? ? //處理錯誤 ? ? } ? ? [session addInput:input];
? ? //創建一個視頻輸出流,并增加到會話。 ? ? AVCaptureVideoDataOutput *output = [[[AVCaptureVideoDataOutput alloc] init] autorelease]; ? ? [session addOutput: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];
? ? //設置FPS ? ? output.minFrameDuration = CMTimeMake(1, 15);
? ? //啟動會話 ? ? [session startRunning];
? ? //將會話與當前控制器關聯 ? ? [self setSession:session]; }
第二步:實現AVCaptureVideoDataOutputSampleBufferDelegate協議方法 ? //當采樣數據被寫入緩沖區時調用 - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer ? ? ? ? ?fromConnection:(AVCaptureConnection *)connection { ? ? //抽取采樣數據,合成UIImage對象 ? ? UIImage *image = [self imageFromSampleBuffer:sampleBuffer]; ? ? //后續自定義處理 ? ? xxxxxxxx }
//抽取采樣數據,合成UIImage對象 - (UIImage *)imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer { ? ? CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); ? ?? ? ? //鎖定像素緩沖區的起始地址 ? ? CVPixelBufferLockBaseAddress(imageBuffer,0);
? ? //獲取每行像素的字節數 ? ? size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); ? ?? ? ? //獲取像素緩沖區的寬度和高度 ? ? size_t width = CVPixelBufferGetWidth(imageBuffer); ? ? size_t height = CVPixelBufferGetHeight(imageBuffer);
? ? //創建基于設備的RGB顏色空間 ? ? CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); ? ? if (!colorSpace) ? ? { ? ? ? ? NSLog(@"CGColorSpaceCreateDeviceRGB failure"); ? ? ? ? return nil; ? ? }
? ? //獲取像素緩沖區的起始地址 ? ? void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); ? ?? ? ? //獲取像素緩沖區的數據大小 ? ? size_t bufferSize = CVPixelBufferGetDataSize(imageBuffer);
? ? //使用提供的數據創建CGDataProviderRef ? ? CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, baseAddress, bufferSize,NULL); ? ?? ? ? //通過CGDataProviderRef,創建CGImageRef ? ? CGImageRef cgImage = ? ? ? ? CGImageCreate(width, ? ? ? ? ? ? ? ? ? ? ? ? height, ? ? ? ? ? ? ? ? ? ? ? ? 8, ? ? ? ? ? ? ? ? ? ? ? ? 32, ? ? ? ? ? ? ? ? ? ? ? ? bytesPerRow, ? ? ? ? ? ? ? ? ? ? ? ? colorSpace, ? ? ? ? ? ? ? ? ? ? ? ? kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little, ? ? ? ? ? ? ? ? ? ? ? ? provider, ? ? ? ? ? ? ? ? ? ? ? ? NULL, ? ? ? ? ? ? ? ? ? ? ? ? true, ? ? ? ? ? ? ? ? ? ? ? ? kCGRenderingIntentDefault); ? ? CGDataProviderRelease(provider); ? ? CGColorSpaceRelease(colorSpace);
? ? //創建UIImage ? ? UIImage *image = [UIImage imageWithCGImage:cgImage]; ? ? CGImageRelease(cgImage);
? ? //解鎖像素緩沖區起始地址 ? ? CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
? ? return image; }
總結
以上是生活随笔為你收集整理的通过AVFoundation框架获取摄像头数据的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: [设计模式] ------ 单例模式
- 下一篇: 消息队列(1):一个消息队列应该有的特点
