Swift 4:获取 UIImage 中像素的 RGB 值

J.T*_*ein 6 colors uicolor ios swift

我知道有很多关于如何在UIImage给定 a 中获取像素颜色的帖子,CGPoint但据我所知,它们都已经过时了。它们中的大多数包含CGImageGetDataProvider并且CGDataProviderCopyData在 Swift 4 中是错误的:

'CGImageGetDataProvider' 已被属性 'CGImage.dataProvider' 替换 'CGDataProviderCopyData' 已被属性 'CGDataProvider.data' 替换

Xcode 建议使用这些替代品,但它们不存在,所以我在尝试重新创建 Swift 4 函数以获取UIImage.

这是典型的 Swift 3 函数:

extension UIImage {

    subscript (x: Int, y: Int) -> UIColor? {

        if x < 0 || x > Int(size.width) || y < 0 || y > Int(size.height) {
            return nil
        }

        let provider = CGImageGetDataProvider(self.cgImage!)
        let providerData = CGDataProviderCopyData(provider!)
        let data = CFDataGetBytePtr(providerData)

        let numberOfComponents = 4
        let pixelData = ((Int(size.width) * y) + x) * numberOfComponents

        let r = CGFloat(data![pixelData]) / 255.0
        let g = CGFloat(data![pixelData + 1]) / 255.0
        let b = CGFloat(data![pixelData + 2]) / 255.0
        let a = CGFloat(data![pixelData + 3]) / 255.0

        return UIColor(red: r, green: g, blue: b, alpha: a)
    }

}
Run Code Online (Sandbox Code Playgroud)

非常感谢任何建议或意见。谢谢!


编辑

我尝试了@Mukesh 的解决方案,但即使修复了所有构建错误,程序还是崩溃了。它说:

我给函数的图像不是nil,我已经检查过。


PS 我用于该功能的图像是相机的快照。我有一个实时摄像头,在每一帧之后,调用此函数(如下)将当前帧转换为UIImage. 这UIImage就是我想要找到的像素颜色:

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        let pixelBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
        let ciImg = CIImage(cvPixelBuffer: pixelBuffer)
        let cameraImage = UIImage(ciImage: ciImg)
        let col = cameraImage.getPixelColor(pos: CGPoint(x: 100, y: 100))
   }
Run Code Online (Sandbox Code Playgroud)

我曾经CGPoint(x: 100, y: 100)以它是否崩溃为例,它确实崩溃了。这一点也在图像中,因为如果不是,它会回到nil这里:

if x < 0 || x > Int(size.width) || y < 0 || y > Int(size.height) {
            return nil
}
Run Code Online (Sandbox Code Playgroud)

有没有办法找出它为什么获得nil价值?或者也许有不同的解决方案?谢谢 :)

Muk*_*esh 3

这是删除错误后得到的代码:

extension UIImage {

    subscript (x: Int, y: Int) -> UIColor? {

        if x < 0 || x > Int(size.width) || y < 0 || y > Int(size.height) {
            return nil
        }

        let provider = self.cgImage!.dataProvider
        let providerData = provider!.data
        let data = CFDataGetBytePtr(providerData)

        let numberOfComponents = 4
        let pixelData = ((Int(size.width) * y) + x) * numberOfComponents

        let r = CGFloat(data![pixelData]) / 255.0
        let g = CGFloat(data![pixelData + 1]) / 255.0
        let b = CGFloat(data![pixelData + 2]) / 255.0
        let a = CGFloat(data![pixelData + 3]) / 255.0

        return UIColor(red: r, green: g, blue: b, alpha: a)
    }
}
Run Code Online (Sandbox Code Playgroud)