Skip to content

Instantly share code, notes, and snippets.

@adamcichy
Created March 15, 2017 15:28
Show Gist options
  • Star 30 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save adamcichy/2d00c7a54009b4a9751ba513749c485e to your computer and use it in GitHub Desktop.
Save adamcichy/2d00c7a54009b4a9751ba513749c485e to your computer and use it in GitHub Desktop.
Determine if a UIImage is generally dark or generally light in Swift 3
extension CGImage {
var isDark: Bool {
get {
guard let imageData = self.dataProvider?.data else { return false }
guard let ptr = CFDataGetBytePtr(imageData) else { return false }
let length = CFDataGetLength(imageData)
let threshold = Int(Double(self.width * self.height) * 0.45)
var darkPixels = 0
for i in stride(from: 0, to: length, by: 4) {
let r = ptr[i]
let g = ptr[i + 1]
let b = ptr[i + 2]
let luminance = (0.299 * Double(r) + 0.587 * Double(g) + 0.114 * Double(b))
if luminance < 150 {
darkPixels += 1
if darkPixels > threshold {
return true
}
}
}
return false
}
}
}
extension UIImage {
var isDark: Bool {
get {
return self.cgImage?.isDark ?? false
}
}
}
@toniocrq
Copy link

toniocrq commented May 22, 2019

I calculated the brightness.
If the brightness is between 34 and 227 the image is good for me.

extension CGImage {
    var brightness: Double {
        get {
            let imageData = self.dataProvider?.data
            let ptr = CFDataGetBytePtr(imageData)
            var x = 0
            var result: Double = 0
            for _ in 0..<self.height {
                for _ in 0..<self.width {
                    let r = ptr![0]
                    let g = ptr![1]
                    let b = ptr![2]
                    result += (0.299 * Double(r) + 0.587 * Double(g) + 0.114 * Double(b))
                    x += 1
                }
            }
            let bright = result / Double (x)
            return bright
        }
    }
}
extension UIImage {
    var brightness: Double {
        get {
            return (self.cgImage?.brightness)!
        }
    }
}

@alvincrisuy
Copy link

Hi @toniocrq thank you for this! though what does 34-227 mean?

@toniocrq
Copy link

toniocrq commented May 28, 2019

@alvincrisuy It's a range that i use for the returned bright.
It goes from 0 to 255.
If the image's brightness is < 34 , the image is too dark, if is > 227 is too bright.

@iamtomcat
Copy link

Nevermind I reread it and it's fine, just jumping the gun thinking I had figured something out.

@rideflag-minh-huynh
Copy link

rideflag-minh-huynh commented Oct 21, 2021

@toniocrq this code is slightly incorrect, you are reading the same pixel every time in the for loop.

Here is my fix
`

       let pixels = self.width*self.height

       let bytesPerPixel = self.bitsPerPixel / self.bitsPerComponent

       var result: Double = 0

        for y in 0..<self.height {
            for x in 0..<self.width {
                let offset = (y * self.bytesPerRow) + (x * bytesPerPixel)
                let r = ptr![offset]
                let g = ptr![offset + 1]
                let b = ptr![offset + 2]

`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment