将CMSampleBuffer转换为数据并将数据转换为UIImage无法正常工作,为什么

时间:2018-11-09 10:04:25

标签: ios swift4

为了测试,我们尝试使用具有以下功能的Swift 4将CMSampleBuffer从捕获输出转换为Data。

获取数据后,我们将该帧数据转换为UIImage并返回nil。我们无法获得UIImage。

我们之所以要进行此测试,是因为我们要将数据发送到另一台设备,以最终获得图像。

但是我们还无法从数据中获取同一设备上的图像。

我们错过了什么吗?

PS:我们将此测试的FPS降低为1。

func captureOutput(_ output: AVCaptureOutput,
                   didOutput sampleBuffer: CMSampleBuffer,
                   from connection: AVCaptureConnection) {

   func frameData() -> (Data) {

        let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)

        CVPixelBufferLockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: 0))

        let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer!)
        let height = CVPixelBufferGetHeight(imageBuffer!)
        let src_buff = CVPixelBufferGetBaseAddress(imageBuffer!)

        let data = Data(bytes: src_buff!, count: bytesPerRow * height)


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


            return (data)

    }

       DispatchQueue.main.async {
         let data = frameData()
         guard let image = UIImage(data) else {return}
         self.myImageView.image = image
     }



 }    

2 个答案:

答案 0 :(得分:0)

您应该使用数据检查UIImage构造函数的文档。我敢肯定,您不能仅使用原始像素数据来构建它,就像您正在做的那样。该构造函数可能期望png或jpeg数据。 pngData()实例上类似UIImage方法的东西。要从原始数据构造图像,可以使用较低的API。 This看起来很有希望,但是您需要将其从目标C移植到Swift或找到类似的解决方案。

您将看到,除了宽度,高度和像素格式之类的原始数据外,还需要多个参数。图像数据并非如此简单。因此,要重建它,您还需要附加此数据。而且由于您要将其发送到另一台设备,因此可能并不容易。

也许一开始最好将其转换为JSON。只需使用以64为基数的字符串即可在字符串和数据之间进行转换:

let dataInstance = Data(base64Encoded: stringInstance)
let stringInstance = dataInstance.base64EncodedString()

所以现在您可以构建一个像这样的字典

let imageJSONDescriptor: [String: Any] = [
    "width": imageWidth,
    "height": imageHeight,
    "rawRGBAData": stringInstance
]

然后创建JSON数据

let JSONData = try! JSONSerialization.data(withJSONObject: imageJSONDescriptor, options: .prettyPrinted

另一方面,收到JSON数据后,您需要将其转换回字典

imageJSONDescriptor = (try! JSONSerialization.jsonObject(with: JSONData, options: .allowFragments)) as! [String: Any]

并获取值

let imageWidth = imageJSONDescriptor["width"] as! Int
let imageHeight = imageJSONDescriptor["height"] as! Int
stringInstance = imageJSONDescriptor["rawRGBAData"] as! String

我希望这可以解决您的问题,但实际上您可能需要的数据不仅仅是宽度和高度。

答案 1 :(得分:0)

好吧,我发现它有点粗糙。

我用

创建数据
  let data = testImage.pngData() as Data?

并流处理此数据,并使用

将其转换为UIImage
  let image = UIImage(data:Data)

但是要做到这一点,我首先将CMSampleBuffer转换为UIImage。