首页 > 代码库 > 自定义相机(三) -- 视频流数据 AND 预览 拍照 变焦
自定义相机(三) -- 视频流数据 AND 预览 拍照 变焦
实现功能:
1. 视频流数据
2. 预览和拍照变焦, 所见即所得。
运行环境:
1. XCODE 5.1.1
2. 真机(IPHONE5 , IOS6.1.4)
#import <UIKit/UIKit.h>#import <AVFoundation/AVFoundation.h> //导入 - "视频流"@interface MCViewController : UIViewController<AVCaptureVideoDataOutputSampleBufferDelegate>@property (strong, nonatomic) AVCaptureSession * captureSession; //AVCaptureSession实例@property (strong, nonatomic) AVCaptureDeviceInput * videoInput; //持有视频输入实例@property (strong, nonatomic) AVCaptureStillImageOutput * stillImageOutput; //持有静态图像输出实例@end
//// MCViewController.m// MyCamera#import "MCViewController.h"@interface MCViewController ()@end@implementation MCViewController#pragma mark - life cycle- (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; //开始扑捉会话 [self.captureSession startRunning];}- (void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; //停止扑捉会话 [self.captureSession stopRunning];}- (void)viewDidLoad{ [super viewDidLoad]; //初始化视频流 [self initAv]; //添加拍照按钮 [self addCaptureButton];}#pragma mark - 初始化视频流- (void) initAv{ //1.1 创建AVCaptureSession self.captureSession = [[AVCaptureSession alloc] init]; //1.2 指定输入设备。这里使用后摄像头。 AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; //1.3 创建AVCaptureDeviceInput的实例,将所选设备作为扑捉会话的输入。 // 此外,在将是其添加到回话前请创建好输入,这里需要做个检查。 NSError * error = nil; self.videoInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; if (self.videoInput) { [self.captureSession addInput:self.videoInput]; } else { NSLog(@"input error : %@", error); } //4. 视频流帧数据 AVCaptureVideoDataOutput * output = [[AVCaptureVideoDataOutput alloc] init]; [self.captureSession 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]; output.videoSettings = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey, [NSNumber numberWithInt: 320], (id)kCVPixelBufferWidthKey, [NSNumber numberWithInt: 240], (id)kCVPixelBufferHeightKey, nil]; //output.minFrameDuration = CMTimeMake(1, 15); //2. 创建预览层 AVCaptureVideoPreviewLayer * previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession]; UIView * aView = self.view; previewLayer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; [aView.layer addSublayer:previewLayer]; [previewLayer setAffineTransform:CGAffineTransformMakeScale(5.0, 5.0)]; //3. 实现拍照 self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; NSDictionary * stillImageOutputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey, nil]; [self.stillImageOutput setOutputSettings:stillImageOutputSettings]; [self.captureSession addOutput:self.stillImageOutput]; // //4. 拍照变焦// AVCaptureConnection * stillImageConnection = [self connectionWithMediaType:AVMediaTypeVideo fromConnections:[self.stillImageOutput connections]];// // [stillImageConnection setVideoScaleAndCropFactor:5.0]; }#pragma mark - - (AVCaptureConnection *)connectionWithMediaType:(NSString *)mediaType fromConnections:(NSArray *)connections{ for ( AVCaptureConnection *connection in connections ) { for ( AVCaptureInputPort *port in [connection inputPorts] ) { if ( [[port mediaType] isEqual:mediaType] ) { return connection; } } } return nil;}#pragma mark - delegate - AVCaptureVideoDataOutputSampleBufferDelegate- (void)captureOutput:(AVCaptureOutput *)captureOutputdidOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{ //视频流一帧数据(UIImage类型) UIImage * image = [self imageFromSampleBuffer:sampleBuffer]; NSLog(@"视频流, 宽:(%f) 高:(%f)", image.size.width, image.size.height); //IPHONE4 720 * 1280 //IPHONE5 1080 * 1920 //或:视频流一帧数据(NSData类型) //NSData * imageData = http://www.mamicode.com/UIImageJPEGRepresentation(image, 0.5);>//Code... }// 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);}#pragma mark - 添加按钮 AND 点击按钮事件- (void)addCaptureButton{ CGRect frame = CGRectMake(0, 0, 100, 100); UIButton * btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; btn.frame = frame; [btn setTitle:@"拍照" forState:UIControlStateNormal]; btn.backgroundColor = [UIColor clearColor]; btn.tag = 1111; [btn addTarget:self action:@selector(onClickCaptureButton:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:btn];}-(IBAction)onClickCaptureButton:(id)sender{ [self takePicture];}#pragma mark - 保持图像到相册- (void)saveImageToPhotos:(UIImage*)savedImage{ UIImageWriteToSavedPhotosAlbum(savedImage, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL);}// 指定回调方法- (void)image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo{ NSString * msg = nil ; if(error != NULL) { msg = @"保存图片失败" ; } else { msg = @"保存图片成功" ; } UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"保存图片结果提示" message:msg delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil]; [alert show];}#pragma mark - 拍照函数//拍照- (void) takePicture{ //1. AVCaptureConnection * stillImageConnection = [self.stillImageOutput.connections objectAtIndex:0]; if ([stillImageConnection isVideoOrientationSupported]) { [stillImageConnection setVideoOrientation:AVCaptureVideoOrientationPortrait]; } //2. [self.stillImageOutput captureStillImageAsynchronouslyFromConnection:stillImageConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) { if (imageDataSampleBuffer != NULL) { //图像数据类型转换 NSData * imageData =http://www.mamicode.com/ [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer]; UIImage * image = [[UIImage alloc] initWithData:imageData]; //保存图像 [self saveImageToPhotos:image]; } else { NSLog(@"Error capturing still image %@", error); } }]; }@end
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。