objccn-iOS上的相机捕捉
在第一台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上的相机捕捉的更多相关文章
- iOS 上的相机捕捉 swift
第一台 iPhone 问世就装有相机.在第一个 SKDs 版本中,在 app 里面整合相机的唯一方法就是使用 UIImagePickerController,但到了 iOS 4,发布了更灵活的 AVF ...
- iOS开发高级分享 - iOS上的设备标识符和指纹
苹果认可的标识符 Apple提供了各种API,以方便用户识别各种用途: 通用标识符(UDID) 在iOS的早期,苹果公司提供了一个uniqueIdentifier财产上UIDevice-亲切地称为ud ...
- 了解iOS上的可执行文件和Mach-O格式
http://www.cocoachina.com/mac/20150122/10988.html http://www.reinterpretcast.com/hello-world-mach-o ...
- 细数iOS上的那些安全防护
细数iOS上的那些安全防护 龙磊,黑雪,蒸米 @阿里巴巴移动安全 0x00 序 随着苹果对iOS系统多年的研发,iOS上的安全防护机制也是越来越多,越来越复杂.这对于刚接触iOS安全的研究人员来说非 ...
- 微信双开是定时炸弹?关于非越狱iOS上微信分身高危插件ImgNaix的分析
作者:蒸米@阿里移动安全 序言 微信作为手机上的第一大应用,有着上亿的用户.并且很多人都不只拥有一个微信帐号,有的微信账号是用于商业的,有的是用于私人的.可惜的是官方版的微信并不支持多开的功能,并且频 ...
- ios上position:fixed失效问题
手机端上的猫腻真是多啊~~~ 此起彼伏! 最近又遇到了 固定定位的底部导航在ios上被弹出去 此时内心1w+个草泥马奔过~~~~~~~~ 直接上解决方案: <div class="ma ...
- :active 为什么在ios上失效
:active是针对鼠标,而手机上是没有鼠标,而是touchstart,所以早成了ios上不兼容 解决方法是: window.onload = function(){ document.body.ad ...
- 解决protobuf不能直接在IOS上使用,利用protobuf-net在IOS上通讯
---------------------------------------------------------------------------------------------------- ...
- iOS上简单推送通知(Push Notification)的实现
iOS上简单推送通知(Push Notification)的实现 根据这篇很好的教程(http://www.raywenderlich.com/3443/apple-push-notification ...
随机推荐
- 简单所以不要忽视,关于\r\n和\n程序员应了解的实际应用
众所周知,\r叫回车符,\n叫换行符. 由于历史原因,windows环境下的换行符是\r\n;(文章最后会稍微解释这个历史原因) linux和html等开源或公开标准中的换行符是\n. 记录这篇笔记的 ...
- 10 行 Python 代码写的模糊查询
导语: 模糊匹配可以算是现代编辑器(在选择要打开的文件时)的一个必备特性了,它所做的就是根据用户输入的部分内容,猜测用户想要的文件名,并提供一个推荐列表供用户选择. 样例如下: Vim (Ctrl-P ...
- [转]Extjs combo数据绑定与获取
原文地址:http://www.cnblogs.com/loveme123/archive/2012/05/10/2494466.html 1. 配置combo: { ...
- bzoj3110
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 5881 Solved: 1958[Submit][Sta ...
- 【kAriOJ】离散数学 构造群码 极大似然法解码
A. 编程题1 构造群码 时间限制 1000 ms 内存限制 65536 KB 题目描述 针对给定H,计算群码编码函数eH,并计算给定字的码字. 输入格式 第一行输入两个整数m,n:(m < n ...
- Linux的学习日记
CURL 在Ubuntu下尝试安装通过包安装Node.js的时候有这样一种安装方法, 那么有必要学学CURL的知识了. curl是利用URL语法在命令行方式下工作的开源文件传输工具.它被广泛应用在Un ...
- Java的多线程机制系列:(一)总述及基础概念
前言 这一系列多线程的文章,一方面是个人对Java现有的多线程机制的学习和记录,另一方面是希望能给不熟悉Java多线程机制.或有一定基础但理解还不够深的读者一个比较全面的介绍,旨在使读者对Java的多 ...
- 机器学习笔记-----Fisher判别式
本文申明:本系列文章为本人原创,如有转载请注明文章原地址. 今天我们机器学习老师在说到周志华老师的<机器学习>这本书的时候,p60页讲到了LDA,但是其中的公式推导省略了很多,现在我来补充 ...
- 学习Javascript
分别归类为: javascript变量 javascript运算符 javascript数组 javascript流程语句 javascript字符串函数 javascript函数基础 javascr ...
- Mac Sublime Text complie python .py error /bin/bash: shell_session_update: command not found
1.get the rvm version rvm -v 2.make sure the version at least 1.26 above. 3.then go ahead rvm get he ...