Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/116.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 将CMSampleBuffer转换为UIImage_Ios_Swift_Uiimage_Cmsamplebuffer - Fatal编程技术网

Ios 将CMSampleBuffer转换为UIImage

Ios 将CMSampleBuffer转换为UIImage,ios,swift,uiimage,cmsamplebuffer,Ios,Swift,Uiimage,Cmsamplebuffer,我正在尝试将sampleBuffer转换为UIImage,并使用colorspaceGray在图像视图中显示它。但它显示为下图。我认为在转换方面存在问题。如何转换CMSampleBuffer 看起来,CMSampleBuffer正在为您提供RGBA数据,然后您可以从中直接构建灰度图像。您可能需要构造一个新的缓冲区,在这里为每个像素执行类似于gray=(pixel.red+pixel.green+pixel.blue)/3的操作。或者,您需要根据接收到的数据创建一个普通RGBA图像,然后将其转换

我正在尝试将sampleBuffer转换为UIImage,并使用colorspaceGray在图像视图中显示它。但它显示为下图。我认为在转换方面存在问题。如何转换CMSampleBuffer


看起来,
CMSampleBuffer
正在为您提供RGBA数据,然后您可以从中直接构建灰度图像。您可能需要构造一个新的缓冲区,在这里为每个像素执行类似于
gray=(pixel.red+pixel.green+pixel.blue)/3的操作。或者,您需要根据接收到的数据创建一个普通RGBA图像,然后将其转换为灰度


但在代码中,根本不进行转换。您使用
CVPixelBufferGetBaseAddress
获取指向缓冲区的原始指针,而不考虑其中的数据类型。然后,在创建图像时只需传递相同的指针,该指针假定接收到的数据为灰度。

转换很简单:

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
     let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
     let ciimage = CIImage(cvPixelBuffer: imageBuffer)   
     let image = self.convert(cmage: ciimage) 
}

// Convert CIImage to UIImage
func convert(cmage: CIImage) -> UIImage {
     let context = CIContext(options: nil)
     let cgImage = context.createCGImage(cmage, from: cmage.extent)!
     let image = UIImage(cgImage: cgImage)
     return image
}

一种更现代的解决方案,具有方向固定功能,无需对CGImage进行性能转换:

func orientation() -> UIImage.Orientation {
    let curDeviceOrientation = UIDevice.current.orientation
    var exifOrientation: UIImage.Orientation
    switch curDeviceOrientation {
        case UIDeviceOrientation.portraitUpsideDown:  // Device oriented vertically, Home button on the top
            exifOrientation = .left
        case UIDeviceOrientation.landscapeLeft:       // Device oriented horizontally, Home button on the right
            exifOrientation = .upMirrored
        case UIDeviceOrientation.landscapeRight:      // Device oriented horizontally, Home button on the left
            exifOrientation = .down
        case UIDeviceOrientation.portrait:            // Device oriented vertically, Home button on the bottom
            exifOrientation = .up
        default:
            exifOrientation = .up
    }
    return exifOrientation
}

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
    guard let imageBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
    let ciimage : CIImage = CIImage(cvPixelBuffer: imageBuffer)
    let image = UIImage.init(ciImage: ciimage, scale: 1.0, orientation: orientation())
}

我认为还可以指定捕获的输出格式,以便捕获输出所需的格式。如果数据已经是灰度的,那么为什么会出现这些条带?为什么不只是一个普通的灰色图像呢?@Matic在这之前我尝试了第一种方法。但它在从上下文生成图像时崩溃,并给出以下错误:copy read only:vm\u copy failed:status1@RubaiyatJahanMumu“如果数据已经是灰度的,那么为什么会出现这些条带?”:很难预测结果,但可能与使用alpha通道(始终为255)作为颜色组件有关。“它在制作图像时崩溃”:您可能有溢出。您需要仔细检查收到的缓冲区,并匹配如何使用它们生成图像。也许缓冲区仍然是RGB。或者您可能正在使用其他类型的缓冲区。让我看看你对bytesPerRow和width的结果。还有什么是比特组件。@rubaiyatjahanmumumu我将从尝试创建普通图像开始。然后试着玩一下如何创建它的灰度版本。谢谢,还有如何将UIImage转换回CMSampleBuffer?完美的解决方案!!谢谢这太棒了!非常感谢。我唯一的问题是图像的方向。它总是默认为风景。你知道为什么会这样,以及如何解决吗that@mikey到目前为止,我记得我在获得图像后旋转了它,或者你可以在中更改图像的方向。hi@mumu我在获得图像后旋转了它。谢谢你的回答!
func orientation() -> UIImage.Orientation {
    let curDeviceOrientation = UIDevice.current.orientation
    var exifOrientation: UIImage.Orientation
    switch curDeviceOrientation {
        case UIDeviceOrientation.portraitUpsideDown:  // Device oriented vertically, Home button on the top
            exifOrientation = .left
        case UIDeviceOrientation.landscapeLeft:       // Device oriented horizontally, Home button on the right
            exifOrientation = .upMirrored
        case UIDeviceOrientation.landscapeRight:      // Device oriented horizontally, Home button on the left
            exifOrientation = .down
        case UIDeviceOrientation.portrait:            // Device oriented vertically, Home button on the bottom
            exifOrientation = .up
        default:
            exifOrientation = .up
    }
    return exifOrientation
}

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
    guard let imageBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
    let ciimage : CIImage = CIImage(cvPixelBuffer: imageBuffer)
    let image = UIImage.init(ciImage: ciimage, scale: 1.0, orientation: orientation())
}