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

6
我知道有很多关于如何获取给定CGPointUIImage的像素颜色的帖子,但据我所知它们都已经过时了。大部分内容包含CGImageGetDataProviderCGDataProviderCopyData,但在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)
    }

}

非常感谢您的建议或评论。谢谢!
编辑 我尝试了@Mukesh的解决方案,虽然所有的构建错误都已经修复,但程序仍然崩溃。它显示: 我检查过传递给函数的图像不是nil
附言:我正在使用相机的快照作为该函数的输入。我有一个实时相机,在每帧之后,我调用这个函数(下面的代码)将当前帧转换为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))
   }

我使用 CGPoint(x: 100, y: 100) 作为示例来测试,结果程序崩溃了。这个点在图片中也存在,否则代码会返回 nil

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

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

你试过这个吗?let provider = self.cgImage!.dataProvider let providerData = provider!.data - Mukesh
1个回答

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

谢谢回复,但即使错误已经消失,程序仍会崩溃。请阅读我帖子的编辑,谢谢! - J.Treutlein
你好,请帮我检查一下我在编辑器中遇到的程序错误。也许你可以看看这个错误是否也会出现在你的代码里,谢谢。 - J.Treutlein
抱歉再次打扰您,不过我想问一下,UIImage的点坐标系是什么?它是UIKit的吗 - 例如,点(0,0)在左上角?谢谢! - J.Treutlein
UIImage和UIView使用左上角作为原点,而Core Image和Core Graphics使用左下角。 - Mukesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接