Search code examples
objective-cswiftuiimageavfoundationavcapturesession

What happens with making UIImage from CMSampleBufferr?


This is a fairly popular question, but I have not found a solution for my issue. I am capturing the frames from the front camera of iPhone this way

func captureOutput(captureOutput: AVCaptureOutput, didOutputSampleBuffer sampleBuffer: CMSampleBufferRef, fromConnection connection: AVCaptureConnection) {
    let uiImage = imageFromSampleBufferDep(sampleBuffer)
    ...
    UIImageWriteToSavedPhotosAlbum(uiImage!, self, "image:didFinishSavingWithError:contextInfo:", nil)
    ...
}

func imageFromSampleBufferDep(sampleBuffer: CMSampleBuffer) -> UIImage? {
    let imageBuffer: CVImageBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer)!
    CVPixelBufferLockBaseAddress(imageBuffer, 0)
    let address = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0)
    let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer) //1924
    let width = CVPixelBufferGetWidth(imageBuffer) //1280
    let height = CVPixelBufferGetHeight(imageBuffer) //720

    let colorSpace = CGColorSpaceCreateDeviceRGB()

    let context = CGBitmapContextCreate(address, width, height, 8, bytesPerRow, colorSpace, CGImageAlphaInfo.NoneSkipFirst.rawValue)
    let imageRef = CGBitmapContextCreateImage(context)

    CVPixelBufferUnlockBaseAddress(imageBuffer, 0)
    var resultImage : UIImage?
    if context != nil {
        resultImage = UIImage(CGImage: imageRef!)
    }

    return resultImage
}

And I've got an error:

<Error>: CGBitmapContextCreate: invalid data bytes/row: should be at least 5120 for 8 integer bits/component, 3 components, kCGImageAlphaNoneSkipFirst.

I tried to assign bytesPerRow to 5120 directly, but in this case I've got a set of gray and inverted pictures(attached)

Hot to fix this issue?

enter image description here


Solution

  • In fact I made a stupid thing which led to an above error.

    Following this convert CMSampleBufferRef to UIImage issue.

    I did so:

    var videoCaptureOutput = AVCaptureVideoDataOutput()
    
    videoCaptureOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey:Int(kCVPixelFormatType_32BGRA)]