最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

ios - Get dominant color from image in SwiftUI? - Stack Overflow

matteradmin6PV0评论

See attached screenshot. How does YouTube do this wherein the mini-player on Android shows a sort of tint overlay as well as tint's the controls in some cases with I'm assuming the dominant/brightest color from the video thumbnail. This also seems random at times for certain videos where despite the thumbnail having a dominant/bright color, the mini-player shows a red tint(presumably since YouTube icon is red) but no/slight tint to the controls. How can this color-picking be done in SwiftUI? Please excuse the accuracy of the color's written in the image, color identification is not really my strong suit :)

See attached screenshot. How does YouTube do this wherein the mini-player on Android shows a sort of tint overlay as well as tint's the controls in some cases with I'm assuming the dominant/brightest color from the video thumbnail. This also seems random at times for certain videos where despite the thumbnail having a dominant/bright color, the mini-player shows a red tint(presumably since YouTube icon is red) but no/slight tint to the controls. How can this color-picking be done in SwiftUI? Please excuse the accuracy of the color's written in the image, color identification is not really my strong suit :)

Share Improve this question edited Nov 16, 2024 at 10:45 batman asked Nov 16, 2024 at 10:31 batmanbatman 2,4582 gold badges27 silver badges52 bronze badges 4
  • I think there is also a tint on the top left image - it's just very desaturated. I don't see any gradients so I don't know where you got that from. "Is there even a pattern or logic here" isn't really a programming question so I'd suggest removing that. "How to get dominant color" could be a valid question, but just be aware that it might not be exactly the same as what Youtube is doing. – Sweeper Commented Nov 16, 2024 at 10:41
  • 1 You might find some of the solutions here (my question) helpful. – Sweeper Commented Nov 16, 2024 at 10:44
  • You're right, gradient wouldn't be the appropriate term here. I wrote that since the tint seemed to fade in the middle to me & looked like a gradient. I've updated the question wording. – batman Commented Nov 16, 2024 at 10:46
  • See also Background blur effect based on image – Benzy Neez Commented Nov 16, 2024 at 12:24
Add a comment  | 

1 Answer 1

Reset to default 1

For videos, the concept is similar but requires extracting a frame from the video first. You can use AVAssetImageGenerator to generate a frame from a video and then pass it to the dominantColor() function

To calculate the dominant (average) color of an image, you can use Core Image's CIFilter.areaAverage. Below is an example that demonstrates how to achieve this in Swift and integrate it with a SwiftUI view. Below is an example extension for UIImage:

import SwiftUI
import CoreImage
import CoreImage.CIFilterBuiltins

extension UIImage {
    func dominantColor() -> UIColor? {
        guard let inputImage = CIImage(image: self) else { return nil }
        
        let filter = CIFilter.areaAverage()
        filter.inputImage = inputImage
        filter.extent = inputImage.extent // Use CGRect directly
        
        let context = CIContext()
        guard let outputImage = filter.outputImage else { return nil }
        
        var bitmap = [UInt8](repeating: 0, count: 4) // RGBA format
        context.render(
            outputImage,
            toBitmap: &bitmap,
            rowBytes: 4,
            bounds: CGRect(x: 0, y: 0, width: 1, height: 1), // 1x1 pixel
            format: .RGBA8,
            colorSpace: CGColorSpaceCreateDeviceRGB()
        )
        
        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
        )
    }
}

This is an example of how to use the dominantColor() method dynamically in a SwiftUI view. It showcases a mini-player with a button to update the dominant color based on different images

struct MiniPlayerView: View {
    @State private var dominantColor: Color = .clear
    @State var selectedImg: UIImage? = UIImage(named: "3")
    
    var body: some View {
        VStack {
            ZStack {
                if let img = selectedImg{
                    Image(uiImage: img)
                }
                
                HStack {
                    Image(systemName: "pause.rectangle.fill")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: 100)
                        .foregroundColor(dominantColor.opacity(0.7))
                        .background(Color.white)
                        .cornerRadius(24.0)
                }
            }
            
            HStack{
                if let img1 = UIImage(named: "1"){
                    Button(action: {
                        selectedImg = img1
                        if let uiColor = selectedImg?.dominantColor() {
                            dominantColor = Color(uiColor)
                        }
                    }, label: {
                        Image(uiImage: img1)
                            .resizable()
                            .frame(width: 70, height: 70)
                    })
                }
                
                if let img1 = UIImage(named: "2"){
                    Button(action: {
                        selectedImg = img1
                        if let uiColor = selectedImg?.dominantColor() {
                            dominantColor = Color(uiColor)
                        }
                    }, label: {
                        Image(uiImage: img1)
                            .resizable()
                            .frame(width: 70, height: 70)
                    })
                }
                
                if let img1 = UIImage(named: "3"){
                    Button(action: {
                        selectedImg = img1
                        if let uiColor = selectedImg?.dominantColor() {
                            dominantColor = Color(uiColor)
                        }
                    }, label: {
                        Image(uiImage: img1)
                            .resizable()
                            .frame(width: 70, height: 70)
                    })
                }
                
                if let img1 = UIImage(named: "4"){
                    Button(action: {
                        selectedImg = img1
                        if let uiColor = selectedImg?.dominantColor() {
                            dominantColor = Color(uiColor)
                        }
                    }, label: {
                        Image(uiImage: img1)
                            .resizable()
                            .frame(width: 70, height: 70)
                    })
                }
            }
        }
        .onAppear {
            if let uiColor = selectedImg?.dominantColor() {
                dominantColor = Color(uiColor)
            }
        }
    }
}

Post a comment

comment list (0)

  1. No comments so far