前言:

最近项目有个需求是对试图对手机密码进行强破解的人进行拍照(通过摄像头截图),因为之前没做过,所以一堆坑。现在就把我的经验都分享出来,希望后来人不用再踏上坑途中。

直接上代码:

  // 创建会话

  self.session = [[AVCaptureSession alloc] init];

// 获取摄像头的权限信息,判断是否有开启权限

AVAuthorizationStatus status    = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];

if (status == AVAuthorizationStatusAuthorized)

{

self.setupResult = AVCamSetupResultSuccess;

}

if ( self.setupResult != AVCamSetupResultSuccess )

return;

self.backgroundRecordingID = UIBackgroundTaskInvalid;

NSError *error = nil;

// 创建输入设备

AVCaptureDevice *videoDevice = [self deviceWithMediaType:AVMediaTypeVideo preferringPosition:AVCaptureDevicePositionFront];

AVCaptureDeviceInput *videoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];

// beginConfiguration这个很重要,在addInput或者addOutput的时候一定要调用这个,add之后再调用commitConfiguration

[self.session beginConfiguration];

if ([self.session canAddInput:videoDeviceInput])

{

[self.session addInput:videoDeviceInput];

self.videoDeviceInput = videoDeviceInput;

}

   // 为会话加入output设备

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

AVCaptureVideoDataOutput *videoDataOutput = [[AVCaptureVideoDataOutput alloc] init];

videoDataOutput.videoSettings =[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA]forKey:               (id)kCVPixelBufferPixelFormatTypeKey];

// 设置self的AVCaptureVideoDataOutputSampleBufferDelegate

[videoDataOutput setSampleBufferDelegate:self queue:videoDataOutputQueue];

if ([self.session canAddOutput:videoDataOutput])

{

[self.session addOutput:videoDataOutput];

}

[self.session commitConfiguration];

// 获取前置摄像头

- (AVCaptureDevice *)deviceWithMediaType:(NSString *)mediaType preferringPosition:(AVCaptureDevicePosition)position{

NSArray *devices = [AVCaptureDevice devicesWithMediaType:mediaType];

AVCaptureDevice *captureDevice = devices.firstObject;

for ( AVCaptureDevice *device in devices ) {

if ( device.position == position ) {

captureDevice = device;

break;

}

}

return captureDevice;

}

// 实现代理方法并获取图片

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{

if (takephoto.isShutScreen)

{

NSLog(@"didOutputSampleBuffer");

UIImage *image  = [self getImageBySampleBufferref:sampleBuffer];

}

}

// 将获取的数据转换成图片,网上很多转换方式转出来的图片都是错误的,最后找到这个方法

- (UIImage *)getImageBySampleBufferref:(CMSampleBufferRef)sampleBuffer

{

CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

/*Lock the image buffer*/

CVPixelBufferLockBaseAddress(imageBuffer,0);

/*Get information about the image*/

uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer);

size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);

size_t width = CVPixelBufferGetWidth(imageBuffer);

size_t height = CVPixelBufferGetHeight(imageBuffer);

/*We unlock the  image buffer*/

CVPixelBufferUnlockBaseAddress(imageBuffer,0);

/*Create a CGImageRef from the CVImageBufferRef*/

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);

CGImageRef newImage = CGBitmapContextCreateImage(newContext);

/*We release some components*/

CGContextRelease(newContext);

CGColorSpaceRelease(colorSpace);

UIImage *image= [UIImage imageWithCGImage:newImage scale:1.0 orientation:UIImageOrientationRight];

NSLog(@"%@", image);

/*We relase the CGImageRef*/

CGImageRelease(newImage);

return image;

}

只要照着我的思路走,就可以达到摄像机截屏的效果,希望能帮到需要的人,如有其他意见,请留言。

AVFoundation之如何从摄像头获取图像的更多相关文章

  1. 如何使用 OpenCV 打开摄像头获取图像数据?

    OpenCV 如何打开摄像头获取图像数据? 代码运行环境:Qt 5.9.1 msvc2015 32bit OpenCV 3.3.0 #include "include/opencv2/ope ...

  2. ROS 教程之 vision : 用各种摄像头获取图像

    可能有很多人想在ROS下学习视觉,先用摄像头获取图像,再用opencv做相应算法处理,可是ROS下图像的采集可不像平常的read一下那么简单,需要借助外部package的使用.而摄像头即可以用笔记本自 ...

  3. android摄像头获取图像——第三弹

    相机获取图像的格式问题 android中承认的格式的参考网址为 :http://developer.android.com/reference/android/graphics/ImageFormat ...

  4. ROS 使用自带和usb摄像头获取图像

    笔记本自带的摄像头的设备号一般为/dev/video0 第一步:安装Webcam 驱动 $ sudo apt-get install git-core $ cd ~/catkin_ws/src $ g ...

  5. Halcon学习之二:摄像头获取图像和相关参数

    1.close_all_framegrabbers ( : : : ) 关闭所有图像采集设备. 2.close_framegrabber ( : : AcqHandle : ) 关闭Handle为Ac ...

  6. android摄像头获取图像——第二弹

    使用android内的Camera对象 (1)Camera是控制着摄像头的api,拥有一系列控制摄像头的上层方法:camera类能够调用底层的摄像头接口,完成启动摄像头.预 览摄像头图像.拍照等功能: ...

  7. android摄像头获取图像——第一弹

    http://www.cnblogs.com/mengyan/archive/2012/09/01/2666636.html 安卓读取视频的几种方式: 详细讲述请参考网址:http://www.cnb ...

  8. GStreamer 从摄像头获取图像 转264

    1.这里有个简单的例子,可以看看GStreamer如何编程的. 2.GStreamer  GstAppSink的官方Document,翻译了一下它的描述部分,点击这里. 3.GStreamer  Gs ...

  9. ffmpeg Windows下采集摄像头一帧数据,并保存为bmp图片

    这里请注意,在编译ffmpeg时,不要使用--disable-devices选项. 使用 --enable-encoder=rawvideo --enable-decoder=rawvideo 启用r ...

随机推荐

  1. 用Redis作为Mysql数据库的缓存

    看到一篇不错的博文,记录下: http://blog.csdn.net/qtyl1988/article/details/39553339 http://blog.csdn.net/qtyl1988/ ...

  2. Collections.sort的两种用法

    http://gwh-08.iteye.com/blog/1233401/ class Foo implements Comparable<Foo>{ @Override public i ...

  3. JS可维护性代码

    最近在看一本Js的书名叫“Javascript高级程序设计”在里面学到了很多东西,是一本不错的书,非常值得一看. 解耦css/javascript element.style.color=" ...

  4. page cache 与free

    我们经常用free查看服务器的内存使用情况,而free中的输出却有些让人困惑,如下: 先看看各个数字的意义以及如何计算得到: free命令输出的第二行(Mem):这行分别显示了物理内存的总量(tota ...

  5. shell编程其实真的很简单(三)

    通过前两篇文章,我们掌握了shell的一些基本写法和变量的使用,以及基本数据类型的运算.那么,本次就将要学习shell的结构化命令了,也就是我们其它编程语言中的条件选择语句及循环语句. 不过,在学习s ...

  6. ASP.NET Core中的缓存[1]:如何在一个ASP.NET Core应用中使用缓存

    .NET Core针对缓存提供了很好的支持 ,我们不仅可以选择将数据缓存在应用进程自身的内存中,还可以采用分布式的形式将缓存数据存储在一个“中心数据库”中.对于分布式缓存,.NET Core提供了针对 ...

  7. Linq 集合操作

    Linq 集合操作 演示代码 两个对象一个是Person,一个Address, AddressId是外键, public class Person { public string ID { get; ...

  8. iOS Foundation框架 -1.常用结构体的用法和输出

    1.安装Xcode工具后会自带开发中常用的框架,存放的地址路径是: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.plat ...

  9. DB2 表空间监控

    默认DB2 缓冲池信息监控是OFF, 需要开启(DB2表空间是由缓冲池分配的) CollBufferpool : ============ The CollBufferpool collector c ...

  10. Java语言基本语法(一)————关键字&标识符(Java语言标识符命名规范&Java语言的包名、类名、接口名、变量名、函数名、常量名命名规则 )

    一.关键字 关键字的定义和特点 定义:被Java语言赋予特殊含义,用做专门用途的字符串(单词). 特点:关键字中所有字母均为小写 下面列举一些常用的关键字. 用于定义数据类型的关键字:byte.sho ...