Технические вопросы и ответы QA1702

Как получить видеокадры от камеры как изображения с помощью Основы AV на iOS

Q: Как я получаю видеокадры от камеры как изображения с помощью Основы AV?

A: Для выполнения получения в реальном времени сначала создайте сеанс получения путем инстанцирования AVCaptureSession объект. Вы используете AVCaptureSession возразите для координирования потока данных от устройств ввода данных AV до выводов.

Затем, создайте входной источник данных, обеспечивающий видеоданные для сеанса получения путем инстанцирования a AVCaptureDeviceInput объект. Вызвать addInput добавить тот ввод к AVCaptureSession объект.

Создайте выходное место назначения путем инстанцирования AVCaptureVideoDataOutput объект, и добавляет его к использованию сеанса получения addOutput.

AVCaptureVideoDataOutput используется для обработки несжатых кадров от получаемого видео. Экземпляр AVCaptureVideoDataOutput производит видеокадры, можно обработать использование других носителей APIs. Можно получить доступ к кадрам с captureOutput:didOutputSampleBuffer:fromConnection: метод делегата. Использовать setSampleBufferDelegate:queue: установить демонстрационного буферного делегата и очередь, на которую должны быть вызваны обратные вызовы. Делегат AVCaptureVideoDataOutputSampleBuffer объект должен принять AVCaptureVideoDataOutputSampleBufferDelegate протокол. Используйте sessionPreset свойство для настройки качества вывода.

Вы вызываете сеанс получения startRunning метод для запуска потока данных от вводов до выводов, и stopRunning остановить поток.

Перечисление 1 показывает пример этого. setupCaptureSession создает сеанс получения, добавляет видеовход для обеспечения видеокадров, добавляет выходное место назначения для доступа к полученным кадрам, затем запускает поток данных от вводов до выводов. В то время как сеанс получения работает, полученные видео демонстрационные буферы отправляются демонстрационному буферному делегату, использующему captureOutput:didOutputSampleBuffer:fromConnection:. Каждый демонстрационный буфер (CMSampleBufferRef) тогда преобразовывается в a UIImage в imageFromSampleBuffer.

Перечисление 1  , Конфигурирующее устройство захвата изображения для записи видео с Основой AV и сохраняющий кадры как UIImage объекты.

#import <AVFoundation/AVFoundation.h>
 
// Create and configure a capture session and start it running
- (void)setupCaptureSession
{
    NSError *error = nil;
 
    // Create the session
    AVCaptureSession *session = [[AVCaptureSession alloc] init];
 
    // Configure the session to produce lower resolution video frames, if your
    // processing algorithm can cope. We'll specify medium quality for the
    // chosen device.
    session.sessionPreset = AVCaptureSessionPresetMedium;
 
    // Find a suitable AVCaptureDevice
    AVCaptureDevice *device = [AVCaptureDevice
                             defaultDeviceWithMediaType:AVMediaTypeVideo];
 
    // Create a device input with the device and add it to the session.
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
                                                                    error:&error];
    if (!input) {
        // Handling the error appropriately.
    }
    [session addInput:input];
 
    // Create a VideoDataOutput and add it to the session
    AVCaptureVideoDataOutput *output = [[[AVCaptureVideoDataOutput alloc] init] autorelease];
    [session addOutput:output];
 
    // Configure your output.
    dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL);
    [output setSampleBufferDelegate:self queue:queue];
    dispatch_release(queue);
 
    // Specify the pixel format
    output.videoSettings =
                [NSDictionary dictionaryWithObject:
                    [NSNumber numberWithInt:kCVPixelFormatType_32BGRA]
                    forKey:(id)kCVPixelBufferPixelFormatTypeKey];
 
 
    // If you wish to cap the frame rate to a known value, such as 15 fps, set
    // minFrameDuration.
    output.minFrameDuration = CMTimeMake(1, 15);
 
    // Start the session running to start the flow of data
    [session startRunning];
 
    // Assign session to an ivar.
    [self setSession:session];
}
 
// Delegate routine that is called when a sample buffer was written
- (void)captureOutput:(AVCaptureOutput *)captureOutput
         didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
         fromConnection:(AVCaptureConnection *)connection
{
    // Create a UIImage from the sample buffer data
    UIImage *image = [self imageFromSampleBuffer:sampleBuffer];
 
     < Add your code here that uses the image >
 
}
 
// Create a UIImage from sample buffer data
- (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer
{
    // Get a CMSampleBuffer's Core Video image buffer for the media data
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    // Lock the base address of the pixel buffer
    CVPixelBufferLockBaseAddress(imageBuffer, 0);
 
    // Get the number of bytes per row for the pixel buffer
    void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
 
    // Get the number of bytes per row for the pixel buffer
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
    // Get the pixel buffer width and height
    size_t width = CVPixelBufferGetWidth(imageBuffer);
    size_t height = CVPixelBufferGetHeight(imageBuffer);
 
    // Create a device-dependent RGB color space
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
 
    // Create a bitmap graphics context with the sample buffer data
    CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8,
      bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
    // Create a Quartz image from the pixel data in the bitmap graphics context
    CGImageRef quartzImage = CGBitmapContextCreateImage(context);
    // Unlock the pixel buffer
    CVPixelBufferUnlockBaseAddress(imageBuffer,0);
 
    // Free up the context and color space
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
 
    // Create an image object from the Quartz image
    UIImage *image = [UIImage imageWithCGImage:quartzImage];
 
    // Release the Quartz image
    CGImageRelease(quartzImage);
 
    return (image);
}


История версии документа


ДатаПримечания
29.09.2010

Обновленный imageFromSampleBuffer кодируют для корректного создания UIImage из демонстрационных буферных данных.

20.07.2010

Новый документ, показывающий, как получить видеокадры от камеры как изображения с помощью Основы AV на iOS