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

时间:2022-03-18 13:20:53

I know there have been lots of posts for how to get the colour of a pixel in a UIImage given a CGPoint but they are all outdated as far as I can tell. Most of them contain CGImageGetDataProvider and CGDataProviderCopyData which in Swift 4 is an error:

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

'CGImageGetDataProvider' has been replaced by property 'CGImage.dataProvider' 'CGDataProviderCopyData' has been replaced by property 'CGDataProvider.data'

'CGImageGetDataProvider'已被属性'CGImage.dataProvider'取代''CGDataProviderCopyData'已被属性'CGDataProvider.data'取代

Xcode suggests these substitutes, but they do not exist so I have been having trouble trying to recreate a Swift 4 function to get the colour of a pixel in a UIImage.

Xcode建议使用这些替代品,但它们不存在,因此我一直无法尝试重新创建Swift 4函数来获取UIImage中像素的颜色。

Here is the typical Swift 3 function:

这是典型的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)
    }

}

Any suggestions or comments are greatly appreciated. Thank you!

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


EDIT

编辑

I tried @Mukesh 's solution but even though all the build errors are fixed, the program crashes. It says:

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

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

The image I give to the function is not nil, I have checked.

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


P.S. The image I am using for the function is a snapshot of the camera. I have a live camera and after every frame, this function (below) is called where I turn the current frame into a UIImage. This UIImage is what I want to find the pixel colour of:

附:我用于该功能的图像是相机的快照。我有一个实时摄像头,在每一帧之后,调用此功能(下面),我将当前帧转换为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))
   }

I used CGPoint(x: 100, y: 100) to see if it crashed as an example, and it did. This point is also in the image because if it wasn't, it would have returned nil here:

我使用CGPoint(x:100,y:100)来查看它是否作为一个例子崩溃了,它确实如此。这一点也在图像中,因为如果不是,它将在这里返回nil:

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

Is there a way to find out why it gets a nil value? Or maybe a different solution? Thank you :)

有没有办法找出它为什么获得零值?或者可能是另一种解决方案谢谢 :)

1 个解决方案

#1


0  

Here is the code I get after removing the errors:

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

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)
    }
}

#1


0  

Here is the code I get after removing the errors:

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

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)
    }
}