想要将摄像头进行视频录制或者拍照可以用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 方法,这样摄像头就开始工作了,这里没有处理关闭什么的,大家可以查文档。
只能在真机中调试,模拟器不可以。