M Zubair Shamshad
M Zubair Shamshad

Reputation: 2741

Detect Colour in a UIImage and save CGPoints

I have a UIImage and I want all the cgPoints of the specific colour this image has. For example I have this Image

enter image description here

Now I want to get the RED colour CGPoints from this UIImage. Red colour may be a straight horizontal/vertical line. It may also be a curved/zigzag line.

This is what I have tried but I m unable to detect the required RED coloured CGPoints.

loop through image size/pixels to detect colour

var requiredPointsInImage = [CGPoint]()
    let testImage = UIImage.init(named: "imgToTest1")
    for heightIteration in 0..<Int(testImage!.size.height) {
        for widthIteration in 0..<Int(testImage!.size.width) {
            let colorOfPoints = testImage!.getPixelColor(pos: CGPoint(x:CGFloat(widthIteration), y:CGFloat(heightIteration)), withFrameSize: testImage!.size)
            if colorOfPoints == MYColor {
                print(colorOfPoints)
                requiredPointsInImage.append(CGPoint(x:CGFloat(widthIteration), y:CGFloat(heightIteration)))
            }

        }
    }

    let newImage = drawShapesOnImage(image: testImage!, points: requiredPointsInImage)

// Colour Detection

extension UIImage {
func getPixelColor(pos: CGPoint, withFrameSize size: CGSize) -> UIColor {
    let x: CGFloat = (self.size.width) * pos.x / size.width
    let y: CGFloat = (self.size.height) * pos.y / size.height
    let pixelPoint: CGPoint = CGPoint(x: x, y: y)
    let pixelData = self.cgImage!.dataProvider!.data
    let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)
    let pixelInfo: Int = ((Int(self.size.width) * Int(pixelPoint.y)) + Int(pixelPoint.x)) * 3 //4

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

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

// Drawing on detected points

func drawShapesOnImage(image: UIImage, points:[CGPoint]) -> UIImage {

    UIGraphicsBeginImageContext(image.size)
    image.draw(at: CGPoint.zero)
    let context = UIGraphicsGetCurrentContext()
    context!.setLineWidth(2.0)
    context!.setStrokeColor(UIColor.green.cgColor)
    let radius: CGFloat = 5.0
    for point in points  {
        let center = CGPoint(x: point.x, y: point.y);
        context!.addArc(center: CGPoint(x: center.x,y: center.y), radius: radius, startAngle: 0, endAngle: 360, clockwise: true)
        context!.strokePath()
    }
    let resultImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return resultImage!
}

This is what I have got .....

enter image description here

Note: Background may not always be white, but of course not RED.

Using the same getPixelColor() function I can get exact color from this below image of any CGPoint but with y constant (say y:1)

enter image description here

If you think there is any other better approach to detect all these points please suggest.

Upvotes: 2

Views: 338

Answers (1)

M Zubair Shamshad
M Zubair Shamshad

Reputation: 2741

SO I have found the solution, Actually the problem was I was ignoring Alpha channel in UIImage extension getPixelColor(). using alpha solve my problem.

here is the updated code!

extension UIImage {
func getPixelColor(pos: CGPoint, withFrameSize size: CGSize) -> UIColor {
let x: CGFloat = (self.size.width) * pos.x / size.width
let y: CGFloat = (self.size.height) * pos.y / size.height
let pixelPoint: CGPoint = CGPoint(x: x, y: y)
let pixelData = self.cgImage!.dataProvider!.data
let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)
let pixelInfo: Int = ((Int(self.size.width) * Int(pixelPoint.y)) + Int(pixelPoint.x)) * 4

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

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

And the result is:

enter image description here

Upvotes: 1

Related Questions