您的位置:首页 > 移动开发 > IOS开发

ios学习--ios将摄像头捕获的视频数据转为jpeg格式 .

2013-05-13 23:05 411 查看
想要将摄像头进行视频录制或者拍照可以用UIImagePickerController,不过UIImagePickerController会弹出一个自己的界面,可是有时候我们不想要弹出的这个界面,那么就可以用另一种方法来获取摄像头得到的数据了。

首先需要引入一个包#import <AVFoundation/AVFoundation.h>,接下来你的类需要实现AVCaptureVideoDataOutputSampleBufferDelegate这个协议,只需要实现协议中的一个方法就可以得到摄像头捕获的数据了

[cpp]
view plaincopyprint?

- (void)captureOutput:(AVCaptureOutput *)captureOutput   
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer   
       fromConnection:(AVCaptureConnection *)connection  
{   
    // Create a UIImage from the sample buffer data  
    UIImage *image = [self imageFromSampleBuffer:sampleBuffer];  
    mData = UIImageJPEGRepresentation(image, 0.5);//这里的mData是NSData对象,后面的0.5代表生成的图片质量  
      
}  

下面是imageFromSampleBuffer方法,方法经过一系列转换,将CMSampleBufferRef转为UIImage对象,并返回这个对象:

[cpp]
view plaincopyprint?

// Create a UIImage from sample buffer data  
- (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];  
    UIImage *image = [UIImage imageWithCGImage:quartzImage scale:1.0f orientation:UIImageOrientationRight];  
      
    // Release the Quartz image  
    CGImageRelease(quartzImage);  
      
    return (image);  
}     

不过要想让摄像头工作起来,还得做一些工作才行:

[cpp]
view plaincopyprint?

// Create and configure a capture session and start it running  
- (void)setupCaptureSession   
{  
    NSError *error = nil;  
      
    // Create the session   
    AVCaptureSession *session = [[[AVCaptureSession alloc] init] autorelease];  
      
    // Configure the session to produce lower resolution video frames, if your   
    // processing algorithm can cope. We'll specify medium quality for the  
    // chosen device.   
    session.sessionPreset = AVCaptureSessionPresetMedium;  
      
    // Find a suitable AVCaptureDevice
  
    AVCaptureDevice *device = [AVCaptureDevice  
                               defaultDeviceWithMediaType:AVMediaTypeVideo];//这里默认是使用后置摄像头,你可以改成前置摄像头  
      
    // Create a device input with the device and add it to the session.  
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device   
                                                                        error:&error];  
    if (!input) {  
        // Handling the error appropriately.  
    }  
    [session addInput:input];  
      
    // Create a VideoDataOutput and add it to the session  
    AVCaptureVideoDataOutput *output = [[[AVCaptureVideoDataOutput alloc] init] autorelease];  
    [session addOutput:output];  
      
    // Configure your output.   
    dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL);  
    [output setSampleBufferDelegate:self queue:queue];  
    dispatch_release(queue);  
      
    // Specify the pixel format  
    output.videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:  
                              [NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey,  
                              [NSNumber numberWithInt: 320], (id)kCVPixelBufferWidthKey,  
                              [NSNumber numberWithInt: 240], (id)kCVPixelBufferHeightKey,  
                              nil];  
      
    AVCaptureVideoPreviewLayer* preLayer = [AVCaptureVideoPreviewLayer layerWithSession: session];  
    //preLayer = [AVCaptureVideoPreviewLayer layerWithSession:session];  
    preLayer.frame = CGRectMake(0, 0, 320, 240);  
    preLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;    
    [self.view.layer addSublayer:preLayer];  
    // If you wish to cap the frame rate to a known value, such as 15 fps, set   
    // minFrameDuration.   
    output.minFrameDuration = CMTimeMake(1, 15);  
      
    // Start the session running to start the flow of data  
    [session startRunning];  
      
    // Assign session to an ivar.   
    //[self setSession:session];  
}  

其中preLayer是一个预览摄像的界面,加不加全看自己了,位置什么的也是在preLayer.frame里可设置。这里强调一下output.videoSettings,这里可以配置输出数据的一些配置,比如宽高和视频的格式。你可以在你这个controller中的初始化调用- (void)setupCaptureSession 方法,这样摄像头就开始工作了,这里没有处理关闭什么的,大家可以查文档。

只能在真机中调试,模拟器不可以。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: