Accelerate Pixel Iteration

The problem I am facing does not allow me to quickly sort through all the pixels in UIImage, checking each color for a specific (green). The iteration should be processed as soon as the user initiates it. There is currently a delay of 0.5 s.

I use this to create a screenshot:

func screenshot() -> UIImage { 

    UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.main.scale)
    view.layer.render(in: UIGraphicsGetCurrentContext()!)
    let screenShot = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return screenShot!  
}

To get the color of one pixel:

extension UIImage {

    func getPixelColor(pos: CGPoint) -> UIColor {

        let pixelData = self.cgImage!.dataProvider!.data
        let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)

        let pixelInfo: Int = ((Int(self.size.width) * Int(pos.y)) + Int(pos.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 this loop to check each pixel of the image:

testImage = screenshot()
greenPresent = false

for yCo in 0 ..< Int(testImage.size.height) {
    for xCo in 0 ..< Int(testImage.size.width) {

        if testImage.getPixelColor(pos: CGPoint(x: xCo, y: yCo)) == UIColor(red: 0, green: 1, blue: 0, alpha: 1) {
            greenPresent = true
            greenCount += 1
        }
    }
}

Any suggestions would be appreciated.

EDIT

Performance is striking in a scale factor of 0.0; I am looking to post it.

+4
source share
3 answers

Here's a more efficient version of the code you posted:

testImage = imageFromView()
var greenCount = 0
if let cfdata = testImage.cgImage?.dataProvider?.data {
    let data = cfdata as Data
    for i in stride(from: 0, to: data.count, by: 4) {
        let r = data[i]
        let g = data[i+1]
        let b = data[i+2]
        if g == 255 && r == 0 && b == 0 {
            greenCount += 1
        }
    }
}

. . . . UIColor. CGFloat.

+4

data:

let data: UnsafePointer<UInt8> = ...

, getPixelColor.

: struct Color class UIColor. ( ), class !


, break . , , -)

+1

, :

yLoop: for yCo in 0 ..< Int(testImage.size.height) {
    for xCo in 0 ..< Int(testImage.size.width) {
        if testImage.getPixelColor(pos: CGPoint(x: xCo, y: yCo)) == UIColor(red: 0, green: 1, blue: 0, alpha: 1) {
            greenPresent = true
            break yLoop
        }
    }
}

, , , , . 50% ( ).

0
source

Source: https://habr.com/ru/post/1675476/


All Articles