在第一台iPhone时,在app里面整合相机的唯一方法就是使用UIImagePickerController。到了iOS4,发布了更灵活的AVFoundation框架。

UIImagePickerController提供了简单的拍照方法,支持所有的基本功能。

AVFoundation框架则提供了完全的访问相机的操作权,eg:以编程方式更改硬件参数,或者操纵实时预览图。

AVFoundation相关类:

AVCaptureDevice 关于相机硬件的接口。被用于控制硬件特性,诸如镜头的位置、曝光、闪光灯等。

AVCaptureDeviceInput 提供来自设备的数据。

AVCaputureOutput 是一个抽象类,描述capture session的结果。有三种关于静态图片捕捉的具体子类:AVCaptureStillImageOutput,AVCaptureMetadataOutput,AVCaptureVideoOutput

AVCaptureSession 管理输入与输出之间的数据流,以及再出现问题时生成运行时错误。

AVCapureVideoPreviewLayer是CALayer的子类,可被用于自动显示相机产生的实时图像。它还有几个工具性质的方法,可将layer上的坐标转化到设备上,看起来像输出,但其实不是,另外,它拥有session。(session拥有outputs),可以用它来实现拍摄预览。

如何捕获图像呢?

1 建立session:AVCaptureSession *tmpSession = [[AVCaptureSession alloc]init];可以设置采集的质量,AVCaptureSessionPresetHigh,Medium,Low,Preset640*480,1280*720,Photo。(preset预设)

[tmpSession startRunning];

重新设置 session

[session beginConfiguration];

// 移除capture device //添加新的capture device // reset the preset

[session commitCongiration];

2 添加input

想创建输入,必须先拥有一个相机设备(或是麦克风)输入。

//我们不能直接创建AVCaptureDevice的实例,只能通过devicesWithMediaType或者defaultDeviceWithMediaType来获取

NSArray *avialableCameraDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];

AVCaptureDevice *backCameraDevice;

AVCaptureDevice *frontCameraDevice;

for (AVCaptureDevice *device in avialableCameraDevices) {

if (device.position == AVCaptureDevicePositionBack) {

backCameraDevice = device;

}

else if (device.position == AVCaptureDevicePositionFront){

frontCameraDevice = device;

}

}

//这时程序就可以设置该对象的对焦模式、闪光灯模式、曝光补偿、白平衡等各种拍照相关的属性了,但需要注意的是在设置各种相关属性之前必须先调用lockForConfiguration方法执行锁定,配置完成后调用unlockForConfiguration解锁

NSError *error = nil;

AVCaptureDeviceInput *frontFacingCameraDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:frontCamera error:&error];

if (!error) {

if ([_session canAddInput:frontFacingCameraDeviceInput]) {

[_session addInput:frontFacingCameraDeviceInput];

self.inputDevice = frontFacingCameraDeviceInput;

}else{

NSLog(@"couldn't add front facing video input");

}

}

3添加output

AVCaptureMovieFileOutput(视频),VideoDataOutput(可以从指定的视频中采集数据),AudioDataOutput(采集音频),StillImageOutput (采集静态图片)

AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc]init];//为了从session中取得数据

if ([captureSession canAddOutput:movieOutput]) {

  [_captureSession addOutput:output];

}else{

  //handle the failure

}

3.2 保存视频到文件用AVCaptureMovieFileOutput 1)声明一个输出,可设置最大录音间隔,可设置最小的可保证影片格式和时间段的磁盘大小 2)配置写到指定文件 3)根据代理确定文件是否写成功。

3.3 对象集截图

3.3.1 设置采集图片的像素格式,设置videoSettings

// Create a VideoDataOutput and add it to the session

AVCaptureVideoDataOutput *output = [[[AVCaptureVideoDataOutput alloc] init] autorelease];

[session addOutput:output];

//线程必须是串行的,确保视频帧按序到达。

dispatch_queue_t videoDataOutputQueue = dispatch_queue_create("VideoDataOutputQueue", DISPATCH_QUEUE_SERIAL);

[output setSampleBufferDelegate:self queue:videoDataOutputQueue];

output.videoSettings = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange] forKey:(id)kCVPixelBufferPixelFormatTypeKey];//设置像素格式

3.3.2 采集静态图片

可以自己指定想要捕捉的格式,下面可以指定捕捉一个jpeg的图片

AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImgeOutput alloc]init];

NSDictionary *outputSettings = @{AVVideoCodeKey:AVVideoCodeJEPG};

[stillImageOutput setOutputSettings:outputSettings];

如果使用JPEG图片格式,就不应该再指定其它的压缩了,output会自动压缩,这个压缩会使用硬件加速。而我们要使用这个图片数据时,可以使用jpegStillImageNSDataRepresentation:这个方法来获取响应的NSData,这个方法不会做重复压缩的动作。(This method merges the image data and Exif metadata sample buffer attachments without re-compressing the image.)

如何捕捉图片:

When you want to capture an image, you send the output a captureStillImageAsynchronouslyFromConnection:completionHandler: message. The first argument is the connection you want to use for the capture. You need to look for the connection whose input port is collecting video:

- (AVCaptureConnection *)findVideoConnection

{

AVCaptureConnection *videoConnection = nil;

for (AVCaptureConnection *connection in _stillImageOutput.connections) {

for (AVCaptureInputPort *port in connection.inputPorts) {

if ([[port mediaType] isEqual:AVMediaTypeVideo]) {

videoConnection = connection;

break;

}

}

if (videoConnection) {

break;

}

}

return videoConnection;

}

- (void)takePicture:(DidCapturePhotoBlock)block

{

AVCaptureConnection *videoConnection = [self findVideoConnection];

[videoConnection setVideoScaleAndCropFactor:_scaleNum];

//CMSampleBuffer 样本缓冲区 包括image data 和一个 errror信息。CMSampleBuffer本身还包含metadata,譬如exif dictionary作为attachment。You can modify the attachments should you want, but note the optimization for JPEG images discussed in “Pixel and Encoding Formats.”

NSLog(@"about to request a capture from:%@",_stillImageOutput);

[_stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer,NSError *error){

CFDictionaryRef exifAttachments = CMGetAttachment(imageDataSampleBuffer, kCGImagePropertyExifDictionary, NULL);

if (exifAttachments) {

NSLog(@"attachements:%@",exifAttachments);

    // do something with the attachments

}

else{

NSLog(@"no attachments");

}

NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];

UIImage *image = [[UIImage alloc]initWithData:imageData];

NSLog(@"oringinImage:%@",[NSValue valueWithCGSize:image.size]);

CGFloat squareLength = [[UIScreen mainScreen] applicationFrame].size.width;

CGFloat headHeight = _previewLayer.bounds.size.height - squareLength;

CGSize size = CGSizeMake(squareLength*2, squareLength*2);

  。。。

}];

}

简书:http://www.jianshu.com/p/9d267825687e

objccn-iOS上的相机捕捉的更多相关文章

  1. iOS 上的相机捕捉 swift

    第一台 iPhone 问世就装有相机.在第一个 SKDs 版本中,在 app 里面整合相机的唯一方法就是使用 UIImagePickerController,但到了 iOS 4,发布了更灵活的 AVF ...

  2. iOS开发高级分享 - iOS上的设备标识符和指纹

    苹果认可的标识符 Apple提供了各种API,以方便用户识别各种用途: 通用标识符(UDID) 在iOS的早期,苹果公司提供了一个uniqueIdentifier财产上UIDevice-亲切地称为ud ...

  3. 了解iOS上的可执行文件和Mach-O格式

    http://www.cocoachina.com/mac/20150122/10988.html http://www.reinterpretcast.com/hello-world-mach-o ...

  4. 细数iOS上的那些安全防护

    细数iOS上的那些安全防护  龙磊,黑雪,蒸米 @阿里巴巴移动安全 0x00 序 随着苹果对iOS系统多年的研发,iOS上的安全防护机制也是越来越多,越来越复杂.这对于刚接触iOS安全的研究人员来说非 ...

  5. 微信双开是定时炸弹?关于非越狱iOS上微信分身高危插件ImgNaix的分析

    作者:蒸米@阿里移动安全 序言 微信作为手机上的第一大应用,有着上亿的用户.并且很多人都不只拥有一个微信帐号,有的微信账号是用于商业的,有的是用于私人的.可惜的是官方版的微信并不支持多开的功能,并且频 ...

  6. ios上position:fixed失效问题

    手机端上的猫腻真是多啊~~~ 此起彼伏! 最近又遇到了 固定定位的底部导航在ios上被弹出去 此时内心1w+个草泥马奔过~~~~~~~~ 直接上解决方案: <div class="ma ...

  7. :active 为什么在ios上失效

    :active是针对鼠标,而手机上是没有鼠标,而是touchstart,所以早成了ios上不兼容 解决方法是: window.onload = function(){ document.body.ad ...

  8. 解决protobuf不能直接在IOS上使用,利用protobuf-net在IOS上通讯

    ---------------------------------------------------------------------------------------------------- ...

  9. iOS上简单推送通知(Push Notification)的实现

    iOS上简单推送通知(Push Notification)的实现 根据这篇很好的教程(http://www.raywenderlich.com/3443/apple-push-notification ...

随机推荐

  1. input 禁止输入法

    <INPUT TYPE = text STYLE = "ime-mode:disabled" > 即可禁止输入法 js形式: active 代表输入法为中文inacti ...

  2. JavaScript indexOf() 方法 和 lastIndexOf() 方法

    indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置. lastIndexOf() 方法可返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索. 语法: in ...

  3. C语言与内存模型初探

    #include<stdio.h> #include<string.h> int main(){ long long int a = 2<<30; char str ...

  4. 1122从业务优化MYSQL

    http://blog.itpub.net/22664653/viewspace-2079576/ 开发反馈一个表的数据大小已经130G,对物理存储空间有影响,且不容易做数据库ddl变更.咨询了开发相 ...

  5. 自定义ViewGroup初步探究

    由于项目需要,实现类似于地图控件,能够让一张图标自由缩放并且在其上固定位置,标记一些地点,所以在这里,我考虑了一下,决定使用自定义ViewGroup来实现.

  6. Java语法

    java语法: 一个java程序可以说是一系列对象的集合,而这些对象都要通过调用彼此的方法来协同工作. 对象: 对象是一个实例,例如:一只猫,它是一个对象,有状态和行为.它的状态状态有:颜色,名字,品 ...

  7. BZOJ 2463: [中山市选2009]谁能赢呢?

    2463: [中山市选2009]谁能赢呢? Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1887  Solved: 1390[Submit][Sta ...

  8. Map工具系列-02-数据迁移工具使用说明

    所有cs端工具集成了一个工具面板 -打开(IE) Map工具系列-01-Map代码生成工具说明 Map工具系列-02-数据迁移工具使用说明 Map工具系列-03-代码生成BySQl工具使用说明 Map ...

  9. Sublime Text 2 实用快捷键(Mac OS X)

    打开/前往: ⌘T 前往文件 ⌘⌃P 前往项目 ⌘R 前往 method ⌘⇧P 命令提示 ⌃G 前往行 ⌃ ` python 控制台 ——————— 编辑: ⌘L 选择行 (重复按下将下一行加入选择 ...

  10. jsContext全局函数调用与对象函数调用、evaluateScript

    evaluateScript:兼具js加载(生成具体的上下文)(函数与通用变量的加载),与函数执行的功能: 函数调用的方式有两种: 1)获取函数(对象),然后执行调用: [context[@" ...