CMSampleBuffer с фронтальной камеры на UIImage

Я пытаюсь создать UIImage из CMSampleBuffer. Следующий код отлично работает для буферов семплов с задней камеры, но не с передней камеры. Когда используется фронтальная камера, CGContext не инициализируется, т. е. конструктор CGContext возвращает nil. Я подозреваю, что мне нужно использовать правильную информацию о растровом изображении, но есть так много комбинаций.

func convert(buffer: CMSampleBuffer) -> UIImage? {

   guard let imageBuffer = CMSampleBufferGetImageBuffer(buffer) else { return nil }

   CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags.readOnly)



   let baseAddress = CVPixelBufferGetBaseAddress(imageBuffer)

   let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer)

   let width = CVPixelBufferGetWidth(imageBuffer)

   let height = CVPixelBufferGetHeight(imageBuffer)



   let colorSpace = CGColorSpaceCreateDeviceRGB()

   var bitmapInfo: UInt32 = CGBitmapInfo.byteOrder32Little.rawValue

   bitmapInfo |= CGImageAlphaInfo.premultipliedFirst.rawValue & CGBitmapInfo.alphaInfoMask.rawValue

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



   guard let quartzImage = context?.makeImage() else { return nil }

   CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags.readOnly)

   let image = UIImage(cgImage: quartzImage)



   return image

}

Это сопровождается следующей ошибкой: «CGBitmapContextCreate: недопустимые байты данных/строка: должно быть не менее 2560 для 8 целочисленных бит/компонент, 3 компонента, kCGImageAlphaPremultipliedFirst».


person Loc Nguyen    schedule 26.02.2018    source источник
comment
Есть ли какие-либо ошибки, или он просто молча терпит неудачу?   -  person brandonscript    schedule 26.02.2018
comment
Добавил ошибку в пост.   -  person Loc Nguyen    schedule 26.02.2018
comment
каков формат данных вашего буфера изображений? Вы уверены, что он содержит ARGB?   -  person Valérian    schedule 26.02.2018
comment
Возможно это? stackoverflow.com/a/24124943/1214800   -  person brandonscript    schedule 26.02.2018
comment
@Valérian Это мой вопрос, я не знаю, что это за формат. Буфер поступает из captureOutup(_ output: AVCaptureOutput, sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) AVCaptureVideoDataOutputSampleBufferDelegate. Указанный формат отлично работает для буфера задней камеры, поэтому я предполагаю, что он будет таким же для передней камеры, но это не так.   -  person Loc Nguyen    schedule 27.02.2018
comment
Будет ли это работать? stackoverflow.com/a/42711035/7831758   -  person adamfowlerphoto    schedule 27.02.2018
comment
CVPixelBufferGetPixelFormatType(imageBuffer) дает вам формат   -  person Valérian    schedule 27.02.2018
comment
Спасибо @Valérian, как мне использовать возвращенное значение OSType для создания UIImage?   -  person Loc Nguyen    schedule 28.02.2018
comment
@Spads, это возвращает мне изображение, но по нескольким конкретным причинам мне нужно пойти по этому пути.   -  person Loc Nguyen    schedule 28.02.2018
comment
Моя интуиция такова, что imageBuffer содержит не RGB, а YUV, и в этом случае вам нужно сначала преобразовать. Что за OSType было возвращено?   -  person Valérian    schedule 28.02.2018
comment
Возвращаемый тип — kCVPixelFormatType_420YpCbCr8BiPlanarFullRange. Я нашел решение, как преобразовать этот буфер в UIImage. Спасибо, что провели меня через это. Теперь мой вопрос: как (если возможно) преобразовать kCVPixelFormatType_32BGRA CASampleBuffer в kCVPixelFormatType_420YpCbCr8BiPlanarFullRange.   -  person Loc Nguyen    schedule 01.03.2018
comment
Либо с VTPixelTransferSession, либо с использованием vImage (это то, что сеанс передачи пикселей использует под капотом)   -  person Valérian    schedule 07.03.2018
comment
VTPixelTransferSession недоступно на iOS. Не могли бы вы поделиться фрагментом для преобразования буфера с помощью vImage?   -  person Loc Nguyen    schedule 08.03.2018