• iPad定制相机界面


      我的应用是iPad上的,工作在Landscape模式,也就是所谓的横屏模式,并且相机界面要定制。首先考虑的当然是UIImagePickerController的cameraOverlayView属性。但是遇到了问题,当iPad旋转后,自定义的视图也会跟着旋转,但是iPhone上就没有问题。尝试子类化UIImagePickerController的- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation方法却没有被调用,很是奇怪,原来官方文档说:“

    Important The UIImagePickerController class supports portrait mode only. This class is intended to be used as-is and does not support subclassing. ”

      我就无语了。既然让自定义视图,为啥旋转得不到响应。

      最终得知定制视图还可以通过另一种方式AVFoundation。这个框架比较底层,更加灵活。所以对此进行了学习,通过不懈努力,终于实现了自己的需求。

    现在把使用AVFoundation捕捉静态图片做个简单的的介绍:

    先来看下AVCaptureSession的工作原理: AVCaptureSession是用来协调控制捕捉设备和输出数据的一个类。

    AVCaptureSession

      捕捉图像至少需要一下几个对象:

    1 AVCaptureDevice:是输入设备的抽象,比如摄像机、麦克风

    AVCaptureInput:用来配置输入设备

    AVCaptureOutput:用来管理输出视频文件或者静态图像

    AVCaptureSession:协调数据从输入设备到输出对象

     

      如果想从摄像头捕捉一张静态图像,那么需要完成一下几个步骤:

      • Create an AVCaptureSession object to coordinate the flow of data from an AV input device to an output

        (创建AVCaptureSession)对象

      • Find the AVCaptureDevice object for the input type you want

        (获取输入设备)

      • Create an AVCaptureDeviceInput object for the device

        (为输入设备创建 AVCaptureDeviceInput对象)

      • Create an AVCaptureVideoDataOutput object to produce video frames

        (创建输出对象用来产生视频帧)

      • Implement a delegate for the AVCaptureVideoDataOutput object to process video frames

        (完成输出协议,处理视频帧)

      • Implement a function to convert the CMSampleBuffer received by the delegate into a UIImage object                                                                              (完成方法实现CMSampleBuffer到UIImage的转换)

    下面是对应具体实现:

    /*创建并配置 Session*/
    AVCaptureSession *session = [[AVCaptureSession alloc] init];
    session.sessionPreset = AVCaptureSessionPresetMedium;
    /*创建并配置输入设备*/
    AVCaptureDevice *device =
            [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
     
    NSError *error = nil;
    AVCaptureDeviceInput *input =
            [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
    if (!input) {
        // Handle the error appropriately.
    }
    [session addInput:input];
    /*创建输出对象*/
    AVCaptureVideoDataOutput *output = [[[AVCaptureVideoDataOutput alloc] init] autorelease]; [session addOutput:output]; output.videoSettings = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]; output.minFrameDuration = CMTimeMake(1, 15);
    dispatch_queue_t queue = dispatch_queue_create("MyQueue", NULL);
    [output setSampleBufferDelegate:self queue:queue];
    dispatch_release(queue);
    /*完成协议*/
    - (void)captureOutput:(AVCaptureOutput *)captureOutput
             didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
             fromConnection:(AVCaptureConnection *)connection {

      NSAutoreleasePool * pool = [[NSAutoreleasePoolalloc] init];

    
        UIImage *image = imageFromSampleBuffer(sampleBuffer);
        // Add your code here that uses the image.

      [pool drain];

    }
    /*开始不抓捕*/
    [session startRunning];

    需要注意的是:创建输出对象的时候,要设定委托对象,并且要在一个新创建的运行队列里,所以使用了 dispatch_queue_t。协议回调的时候是运行在这个队列中的,所以在协议处理函数中要增加内存池。

    以上就是基本的用法,下面贴出我根据书上的一个例子改装的Demo。实现过程中遇到了问题,就是屏幕旋转的时候,实时画面反转错误。所以在旋转的时候,要更改

    AVCaptureVideoPreviewLayer的方向。还是看代码吧!

    https://github.com/cokecoffe/ios-demo/tree/master/CameraWithAVFoudation

  • 相关阅读:
    VMwarePlayer虚拟机下centos6的静态IP配置
    C/C++ 父子进程之间的文件描述符问题
    C++ wait捕捉的信号处理WIFEXITED/WEXITSTATUS/WIFSIGNALED
    WIN7下用笔记本创建无线网
    C++ readdir、readdir_r函数
    C++ int转string(stringstream可转更多类型)
    C/C++函数中使用可变参数
    C/C++中static关键字作用总结
    Unix网络编程第三版源码编译
    Linux下初次使用github
  • 原文地址:https://www.cnblogs.com/cokecoffe/p/2592701.html
Copyright © 2020-2023  润新知