iOS疯狂详解之将摄像头捕获的视频数据转为jpeg格式

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

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

 

- (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对象,并返回这个对象:

 

 

// 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);  
}     

 

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

 

// 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 方法,这样摄像头就开始工作了,这里没有处理关闭什么的,大家可以查文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值