UIImagePickerController: получение изображения из видео - PullRequest
5 голосов
/ 17 февраля 2011

Я пытаюсь извлечь кадр из видео в качестве изображения.Видео записывается с использованием UIImagePickerController.

Когда видео записано, я получаю его URL и загружаю его с помощью AVURLAsset.Затем я создаю AVAssetReader и AVAssetReaderTrackOutput, чтобы получить отдельные кадры.

Когда я получаю кадры как CMSampleBufferRef, я передаю их методу Apple imageFromSampleBuffer, который должен вернуть UIImage.Этот метод работал нормально, когда я получал кадры с использованием AVCaptureSession, но когда я использую видео, записанное с помощью UIImagePickerController, эта строка возвращает 0x0:

CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 

Где sampleBuffer - это CMSampleBufferRed, который я передаю.

Я проверил значение sampleBuffer через отладчик, и оно выглядело нормально (не 0x0).Есть ли какая-либо причина, по которой CMSampleBufferGetImageBuffer будет возвращать 0x0?

Или альтернативно есть другой способ извлечь отдельный видеокадр из файла MOV и сохранить его как UIImage?

Спасибо.

Ответы [ 2 ]

7 голосов
/ 17 февраля 2011

Я нашел решение.Вы должны установить формат пикселей в настройках, переданных при инициализации AVAssetReaderTrackOutput.

Я передал следующий словарь настроек:

NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey;
NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];
NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key]; 

Надеюсь, это поможет кому-то еще.

0 голосов
/ 10 ноября 2018

Я так и сделал некоторое время назад.

    func getPicture() -> UIImage {



        let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!

        var videoWidth = CVPixelBufferGetWidth(imageBuffer)
        var videoHeight = CVPixelBufferGetHeight(imageBuffer)



        CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))

        // Creating an image from a imageBuffer, a frame.
        let baseAddress = CVPixelBufferGetBaseAddress(imageBuffer)
        let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer) 
        let colorSpace  = CGColorSpaceCreateDeviceRGB()  
        var bitmapInfo  = CGBitmapInfo.byteOrder32Little.rawValue
        bitmapInfo |= CGImageAlphaInfo.premultipliedFirst.rawValue 


        let context = CGContext(data: baseAddress, width: videoWidth, height: videoHeight, bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo)!

        let frameImage =   context.makeImage()!  // This is a CGImage
        let image =  UIImage(cgImage: frameImage) 

        return image

    }
...