【问题标题】:Data via Buffer Post Xcode 11.5 Update通过 Buffer Post Xcode 11.5 更新的数据
【发布时间】:2023-04-03 03:03:01
【问题描述】:

我有什么:

引用Apple's Chroma Key Code,它指出我们可以通过

func chromaKeyFilter(fromHue: CGFloat, toHue: CGFloat) -> CIFilter?
{
    // 1
    let size = 64
    var cubeRGB = [Float]()
        
    // 2
    for z in 0 ..< size {
        let blue = CGFloat(z) / CGFloat(size-1)
        for y in 0 ..< size {
            let green = CGFloat(y) / CGFloat(size-1)
            for x in 0 ..< size {
                let red = CGFloat(x) / CGFloat(size-1)
                    
                // 3
                let hue = getHue(red: red, green: green, blue: blue)
                let alpha: CGFloat = (hue >= fromHue && hue <= toHue) ? 0: 1
                    
                // 4
                cubeRGB.append(Float(red * alpha))
                cubeRGB.append(Float(green * alpha))
                cubeRGB.append(Float(blue * alpha))
                cubeRGB.append(Float(alpha))
            }
        }
    }

    let data = Data(buffer: UnsafeBufferPointer(start: &cubeRGB, count: cubeRGB.count))

    // 5
    let colorCubeFilter = CIFilter(name: "CIColorCube", withInputParameters: ["inputCubeDimension": size, "inputCubeData": data])
    return colorCubeFilter
}

然后我创建了一个函数,可以将任何图像插入此过滤器并返回过滤后的图像。

public func filteredImage(ciimage: CIImage) -> CIImage? {
    let filter = chromaKeyFilter(fromHue: 110/360, toHue: 130/360)! //green screen effect colors
    filter.setValue(ciimage, forKey: kCIInputImageKey)
    return RealtimeDepthMaskViewController.filter.outputImage
}

然后我可以在任何图像上执行此功能并获得色度键图像。

if let maskedImage = filteredImage(ciimage: ciimage) {
    //Do something
}
else {
    print("Not filtered image")
}

更新问题:

let data = Data(buffer: UnsafeBufferPointer(start: &amp;cubeRGB, count: cubeRGB.count))

但是,一旦我将 Xcode 更新到 v11.6,我会在上面的代码行中收到警告 Initialization of 'UnsafeBufferPointer&lt;Float&gt;' results in a dangling buffer pointer 以及运行时错误 Thread 1: EXC_BAD_ACCESS (code=1, address=0x13c600020)

我尝试使用this 解决此问题,以更正 Swift 的新 UnsafeBufferPointer 警告。然后警告被纠正,我不再有运行时错误。

问题

现在,虽然没有出现警告并且我没有遇到运行时错误,但我仍然收到打印语句Not filtered image。我认为问题源于处理或删除数据的方式,不完全确定如何正确处理 UnsafeBufferPointersData

正确获取色度键的Data 的适当方法是什么?

【问题讨论】:

    标签: swift unsafe-pointers chromakey


    【解决方案1】:

    我不确定RealtimeDepthMaskViewController 在这种情况下是什么,所以只返回了过滤器输出。抱歉,如果这意味着保持原样。还添加了一个可能返回 nil 的保护语句 - 它与函数的可选返回类型相匹配。

    public func filteredImage(ciImage: CIImage) -> CIImage? {
        guard let filter = chromaKeyFilter(fromHue: 110/360, toHue: 130/360) else { return nil }
        filter.setValue(ciImage, forKey: "inputImage")
        return filter.outputImage // instead of RealtimeDepthMaskViewController.filter.outputImage
    }
    

    对于悬空指针编译器警告,我找到了几种方法:

    // approach #1
    var data = Data()
    cubeRGB.withUnsafeBufferPointer { ptr in
        data = Data(buffer: ptr)
    }
    
    // approach #2
    let byteCount = MemoryLayout<Float>.size * cubeRGB.count
    let data = Data(bytes: &cubeRGB, count: byteCount)
    

    一个警告:使用 Xcode 11.6 而不是 11.5 进行查看

    【讨论】:

    • 我最终在您回答之前想出了解决方案,但完全忘记了这篇文章!但是,既然您确实回答了,我会把它交给您:) 然而,对我来说有一些不同的事情; var data = Data() 必须是 [UInt8] 类型。 data.append(contentsOf: $0) 而不是 data = Data(buffer: ptr) 最后,CIFilter 需要接收 NSData,因此您需要执行类似 let finalData = NSData(bytes: data, length: data.count 的操作。不过,感谢您的回答!
    • 这个答案对@lentil 很有帮助。但是你知道为什么进程会阻塞主线程吗?在返回最终图像之前,主线程上的所有 UI 活动都被冻结。
    • 嗨@UmitKaya。很高兴你发现这很有用!关于您的线程问题-原始帖子未指定调用该方法的上下文,但是如果您从 main 调用该方法,它将阻塞直到返回。考虑在某种回调中调用该方法 - 或将工作提交到调度队列。
    • 看来,CoreML 在主线程上使用 GPU。这是一项繁重的工作,会导致主线程冻结一两秒钟。他们之前在这里也讨论过这个问题:developer.apple.com/forums/thread/92996 无论如何,我能够将 CoreML 移动到后台线程并在返回结果后同步到主线程。感谢您的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-02
    • 1970-01-01
    • 2020-09-15
    • 2017-12-26
    • 2014-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多