Reputation: 983
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:
'CGImageGetDataProvider' has been replaced by property 'CGImage.dataProvider' 'CGDataProviderCopyData' has been replaced by property '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
.
Here is the typical Swift 3 function:
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:
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:
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:
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 :)
Upvotes: 6
Views: 7055
Reputation: 2902
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)
}
}
Upvotes: 3