• AVFoundation之如何从摄像头获取图像


    前言:

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

    直接上代码:

      // 创建会话

      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;

    }

      

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

  • 相关阅读:
    (6)UIView常见属性二
    linux系统中不间断会话服务screen命令
    linux系统中配置sshd服务(远程控制服务)
    Linux系统中远程传输命令scp
    linux系统中防火墙管理工具iptables
    什么是端口?
    linux系统实现会话共享功能
    linux系统中远程控制服务安全密码验证 sshkeygen命令
    linux系统中防火墙策略管理工具firewalld
    linux系统中nmcli命令、查看、添加、删除、编辑网络会话
  • 原文地址:https://www.cnblogs.com/destiLaugh/p/6552569.html
Copyright © 2020-2023  润新知