解决方法
如何使用AVFoundation前置摄像头捕获图像:
发展注意事项:
>仔细检查你的应用程序和图像方向设置
> AVFoundation及其相关框架是讨厌的巨兽,非常难以理解/实施.我使我的代码尽可能精简,但请查看这个优秀的教程,以获得更好的解释(网站不再提供,通过archive.org链接):
http://www.benjaminloulier.com/posts/ios4-and-direct-access-to-the-camera
ViewController.h
// Frameworks #import <CoreVideo/CoreVideo.h> #import <CoreMedia/CoreMedia.h> #import <AVFoundation/AVFoundation.h> #import <UIKit/UIKit.h> @interface CameraViewController : UIViewController <AVCaptureVideoDataOutputSampleBufferDelegate> // Camera @property (weak,nonatomic) IBOutlet UIImageView* cameraImageView; @property (strong,nonatomic) AVCaptureDevice* device; @property (strong,nonatomic) AVCaptureSession* captureSession; @property (strong,nonatomic) AVCaptureVideoPreviewLayer* previewLayer; @property (strong,nonatomic) UIImage* cameraImage; @end
ViewController.m
#import "CameraViewController.h" @implementation CameraViewController - (void)viewDidLoad { [super viewDidLoad]; [self setupCamera]; [self setupTimer]; } - (void)setupCamera { NSArray* devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; for(AVCaptureDevice *device in devices) { if([device position] == AVCaptureDevicePositionFront) self.device = device; } AVCaptureDeviceInput* input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil]; AVCaptureVideoDataOutput* output = [[AVCaptureVideoDataOutput alloc] init]; output.alwaysDiscardsLateVideoFrames = YES; dispatch_queue_t queue; queue = dispatch_queue_create("cameraQueue",NULL); [output setSampleBufferDelegate:self queue:queue]; NSString* key = (NSString *) kCVPixelBufferPixelFormatTypeKey; NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key]; [output setVideoSettings:videoSettings]; self.captureSession = [[AVCaptureSession alloc] init]; [self.captureSession addInput:input]; [self.captureSession addOutput:output]; [self.captureSession setSessionPreset:AVCaptureSessionPresetPhoto]; self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession]; self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; // CHECK FOR YOUR APP self.previewLayer.frame = CGRectMake(0,self.view.frame.size.height,self.view.frame.size.width); self.previewLayer.orientation = AVCaptureVideoOrientationLandscapeRight; // CHECK FOR YOUR APP [self.view.layer insertSublayer:self.previewLayer atIndex:0]; // Comment-out to hide preview layer [self.captureSession startRunning]; } - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); CVPixelBufferLockBaseAddress(imageBuffer,0); uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer); size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); size_t width = CVPixelBufferGetWidth(imageBuffer); size_t height = CVPixelBufferGetHeight(imageBuffer); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef newContext = CGBitmapContextCreate(baseAddress,width,height,8,bytesPerRow,colorSpace,kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); CGImageRef newImage = CGBitmapContextCreateImage(newContext); CGContextRelease(newContext); CGColorSpaceRelease(colorSpace); self.cameraImage = [UIImage imageWithCGImage:newImage scale:1.0f orientation:UIImageOrientationDownMirrored]; CGImageRelease(newImage); CVPixelBufferUnlockBaseAddress(imageBuffer,0); } - (void)setupTimer { NSTimer* cameraTimer = [NSTimer scheduledTimerWithTimeInterval:2.0f target:self selector:@selector(snapshot) userInfo:nil repeats:YES]; } - (void)snapshot { NSLog(@"SNAPSHOT"); self.cameraImageView.image = self.cameraImage; // Comment-out to hide snapshot } @end
将其连接到具有UIImageView的UIViewController用于快照,它将工作!快照以2.0秒的间隔以编程方式进行,无任何用户输入.注释所选行以删除预览图层和快照反馈.
任何更多的问题/意见,请让我知道!