2015-01-15 3 views
3

Вот функция (код от компании Apple документации), которая преобразует CMSampleBuffer в UIImageПреобразование CMSampleBuffer в UIImage

func imageFromSampleBuffer(sampleBuffer: CMSampleBuffer) -> UIImage { 
    // Get a CMSampleBuffer's Core Video image buffer for the media data 
    var 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 
    var baseAddress = CVPixelBufferGetBaseAddress(imageBuffer) 

    // Get the number of bytes per row for the pixel buffer 
    var bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer) 
    // Get the pixel buffer width and height 
    var width = CVPixelBufferGetWidth(imageBuffer) 
    var height = CVPixelBufferGetHeight(imageBuffer) 

    // Create a device-dependent RGB color space 
    var colorSpace = CGColorSpaceCreateDeviceRGB() 

    // Create a bitmap graphics context with the sample buffer data 
    let bitmapInfo = CGBitmapInfo(CGImageAlphaInfo.NoneSkipLast.rawValue) 
    var context = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, bitmapInfo) 
    // Create a Quartz image from the pixel data in the bitmap graphics context 
    var quartzImage = CGBitmapContextCreateImage(context); 
    // Unlock the pixel buffer 
    CVPixelBufferUnlockBaseAddress(imageBuffer,0); 

    // Create an image object from the Quartz image 
    var image = UIImage(CGImage: quartzImage)! 

    return image 
} 

Когда я пытаюсь визуализировать UIImage с помощью UIImageView, я ничего не получаю.
Любые идеи?

+0

Потребность Вы получаете ошибки в выводе Xcode? –

ответ

1

Это решение для Swift 3.0, где CMSampleBuffer продлен, создавая переменную, которая дает вам дополнительный UIImage.

import AVFoundation 

extension CMSampleBuffer { 
    var uiImage: UIImage? { 
     guard let imageBuffer = CMSampleBufferGetImageBuffer(self) else { return nil } 

     CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0)) 
     let baseAddress = CVPixelBufferGetBaseAddress(imageBuffer) 
     let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer) 
     let width = CVPixelBufferGetWidth(imageBuffer) 
     let height = CVPixelBufferGetHeight(imageBuffer) 
     let colorSpace = CGColorSpaceCreateDeviceRGB() 
     let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.noneSkipFirst.rawValue | CGBitmapInfo.byteOrder32Little.rawValue) 
     guard let context = CGContext(data: baseAddress, 
             width: width, 
             height: height, 
             bitsPerComponent: 8, 
             bytesPerRow: bytesPerRow, 
             space: colorSpace, 
             bitmapInfo: bitmapInfo.rawValue) else { return nil } 
     guard let cgImage = context.makeImage() else { return nil } 

     CVPixelBufferUnlockBaseAddress(imageBuffer,CVPixelBufferLockFlags(rawValue: 0)); 

     return UIImage(cgImage: cgImage) 
    } 
} 
+2

Я получаю: : CGBitmapContextCreate: недопустимые данные bytes/row: должно быть не менее 5120 для 8 целых битов/компонентов, 3 компонента, kCGImageAlphaNoneSkipFirst – Zigglzworth

+0

@Zigglzworth У вас может быть изображение в оттенках серого. Вы можете соответствующим образом скорректировать значения для них. – CodeBender

+0

Хмм не было этого .. не уверен, почему это не сработало для меня – Zigglzworth

4

Я только что закончил ту же самую функцию в моем текущем проекте, и вот как я получил его на работу (с большим количеством прибегая к помощи и некоторых проб и ошибок):

let bitmapInfo = CGBitmapInfo(CGImageAlphaInfo.NoneSkipFirst.rawValue | CGBitmapInfo.ByteOrder32Little.rawValue) 

Кроме того, убедитесь, вы представляете UIImageView в основном потоке (вы, вероятно, находитесь в потоке сеанса камеры, чтобы получить CMSampleBuffer), потому что UIKit может выполняться только в основном потоке. В противном случае вам придется подождать очень и очень долго, пока изображение не появится.

+0

Что лучше всего получить UIImage из 'bitmapInfo'? – Alston

1

@Zigglzworth установка kCVPixelFormatType_32BGRA для captureVideoDataOutput

 let videoOutput = AVCaptureVideoDataOutput() 
     videoOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as AnyHashable:kCVPixelFormatType_32BGRA] 
Смежные вопросы