AVCaptureVideoPreviewLayer: создание снимка - PullRequest
13 голосов
/ 03 августа 2010

Я пытаюсь эмулировать анимацию, видимую в приложении камеры по умолчанию, где снимок видоискателя камеры анимируется в углу экрана приложения.

Объект AVCaptureVideoPreviewLayer, который содержит ключ к решению этой проблемы, не очень открыт для этих требований: попытка создать его копию на новом слое с помощью ..

- (id)initWithLayer:(id)layer

.. возвращает пустой слой без снимка изображения, поэтому очевидно, что здесь происходит более глубокая магия.

Ваши подсказки / приветствия приветствуются.

М. * * +1010

Ответы [ 4 ]

22 голосов
/ 10 августа 2010

сталкиваются с теми же трудностями, под немного другим углом.

Вот возможные решения, которые не слишком велики IMO:

  • Вы можете добавить к AVCaptureSession и AVCaptureStillImageOutput и AVCaptureVideoDataOutput .Когда вы установите sessionPreset в AVCaptureSessionPresetHigh , вы начнете получать кадры с помощью API, а при переключении на AVCaptureSessionPresetPhoto вы сможете получать реальные изображения.Поэтому прямо перед съемкой вы можете переключиться на видео, получить кадр, а затем вернуться к камере.Главное предостережение заключается в том, что переключение камеры между видеокамерой и фотокамерой занимает «большое» время (пару секунд).

  • Другим вариантом будет использование только камеры.вывод ( AVCaptureStillImageOutput ) и использование UIGetScreenImage для получения снимка экрана телефона.Затем вы можете обрезать элементы управления и оставить только изображение.Это усложняется, если вы показываете элементы управления пользовательского интерфейса над изображением.Кроме того, согласно этой записи, Apple начала отклонять приложения, которые используют эту функцию (это всегда было ненадежно).

  • Помимо них я также пытался играть с AVCaptureVideoPreviewLayer .Это это сообщение, чтобы сохранить UIView или CALayer в UIImage.Но все это дает четкие или белые изображения.Я попытался получить доступ к слою, слою вида, суперслой , presentationLayer , modelLayer , но безрезультатно.Я предполагаю, что данные в AVCaptureVideoPreviewLayer являются очень внутренними и не являются частью инфраструктуры обычного уровня.

Надеюсь, это поможет, Одед.

5 голосов
/ 27 ноября 2012

Я думаю, что вы должны добавить AVCaptureVideoDataOutput к текущей сессии с:

AVCaptureVideoDataOutput *videoOutput = [[AVCaptureVideoDataOutput alloc] init];
videoOutput.videoSettings = @{ (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA) };
[session addOutput:videoOutput];

dispatch_queue_t queue = dispatch_queue_create("MyQueue", NULL);
[videoOutput setSampleBufferDelegate:self queue:queue];
dispatch_release(queue);

Затем реализуйте метод делегата ниже, чтобы получить снимок вашего изображения:

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

    UIImage *image = [self imageFromSampleBuffer:sampleBuffer];
    // Add your code here that uses the image.
    dispatch_async(dispatch_get_main_queue(), ^{
        _imageView.image = image;
    });   
}

Это потребляет память и снижает производительность приложения. Чтобы улучшить, вы также можете оптимизировать свой AVCaptureVideoDataOutput с помощью:

videoOutput.minFrameDuration = CMTimeMake(1, 15);

Вы также можете использовать alwaysDiscardsLateVideoFrames.

0 голосов
/ 25 июля 2015

Начиная с iOS 7, вы можете использовать UIView :: snapshotViewAfterScreenUpdates для создания снимка UIView, обертывающего ваш AVCaptureVideoPreviewLayer.Это не то же самое, что UIGetScreenImage, из-за которого ваше приложение будет отклонено.

UIView *snapshot = [self.containerView snapshotViewAfterScreenUpdates:YES];

Вспомните старый способ превращения вида в изображение.По некоторым причинам это работало на всем, кроме предварительного просмотра камеры:

UIGraphicsBeginImageContextWithOptions(self.containerView.bounds.size, NO, [UIScreen mainScreen].scale);
[self.containerView drawViewHierarchyInRect:self.containerView.bounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
0 голосов
/ 25 августа 2010

есть 2 способа получить кадры предварительного просмотра. AVCaptureVideoDataOutput и AVCaptureStillImageOutput:)

- ваш сеанс захвата настроен для захвата видеокадров, а затем для создания слоя с изображением из выбранного кадра. если он настроен для неподвижных изображений, подождите, пока получите неподвижное изображение, и создайте слой из уменьшенной версии этого cgimage. если у вас еще нет вывода в сеансе, вам придется добавить один, я думаю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...