how to detect major color in an image in iOS

I have a swiftui view that displays a picture which users select from Photo app and shows some texts below the picture. I want to dynamically tune the background color of the view depending on the picture major color. Say, if users select a grass or forest image, the background auto changes to green. Is there any best practice?

Answered by Claude31 in 746000022

picture major color

That's the challenge, defining it.

If I had to do it, I would do the following

  • Compute the distribution of colours in the image
  • Identify the maximum colour in the distribution

To compute distribution, use CIFilter CIAreaHistogram

and how to use histogram

See how to use a CIFilter (here to compute average colour, which is not what you are looking for) https://www.hackingwithswift.com/example-code/media/how-to-read-the-average-color-of-a-uiimage-using-ciareaaverage

Accepted Answer

picture major color

That's the challenge, defining it.

If I had to do it, I would do the following

  • Compute the distribution of colours in the image
  • Identify the maximum colour in the distribution

To compute distribution, use CIFilter CIAreaHistogram

and how to use histogram

See how to use a CIFilter (here to compute average colour, which is not what you are looking for) https://www.hackingwithswift.com/example-code/media/how-to-read-the-average-color-of-a-uiimage-using-ciareaaverage

You can try this , it work for me :

import SwiftUI import CoreImage import CoreImage.CIFilterBuiltins import UIKit

struct ContentView: View { var body: some View { if let image = UIImage(named: "ka") { DominantColorView(image: image) } else { Text("Image not found") } } }

func extractDominantColor(from image: UIImage) -> UIColor? { guard let inputImage = CIImage(image: image) else { return nil }

let extentVector = CIVector(x: inputImage.extent.origin.x, y: inputImage.extent.origin.y, z: inputImage.extent.size.width, w: inputImage.extent.size.height)

guard let filter = CIFilter(name: "CIAreaAverage", parameters: [kCIInputImageKey: inputImage, kCIInputExtentKey: extentVector]) else { return nil }
guard let outputImage = filter.outputImage else { return nil }

var bitmap = [UInt8](repeating: 0, count: 4)
let context = CIContext(options: [.workingColorSpace: kCFNull!])
context.render(outputImage, toBitmap: &bitmap, rowBytes: 4, bounds: CGRect(x: 0, y: 0, width: 1, height: 1), format: .RGBA8, colorSpace: nil)

return UIColor(red: CGFloat(bitmap[0]) / 255.0, green: CGFloat(bitmap[1]) / 255.0, blue: CGFloat(bitmap[2]) / 255.0, alpha: CGFloat(bitmap[3]) / 255.0)

} struct DominantColorView: View { let image: UIImage

var dominantColor: Color {
    if let uiColor = extractDominantColor(from: image) {
        return Color(uiColor)
    } else {
        return Color.clear
    }
}

var body: some View {
    ZStack {
        dominantColor
        Image(uiImage: image)
            .resizable()
            .scaledToFit()
            .frame(height: 200)
            .shadow(radius: /*@START_MENU_TOKEN@*/10/*@END_MENU_TOKEN@*/, x: -12, y: 12)
        
    }
}

}

how to detect major color in an image in iOS
 
 
Q