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