admin管理员组文章数量:1026989
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
1 Answer
Reset to default 1For 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)
}
}
}
}
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
1 Answer
Reset to default 1For 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)
}
}
}
}
本文标签: iosGet dominant color from image in SwiftUIStack Overflow
版权声明:本文标题:ios - Get dominant color from image in SwiftUI? - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745660722a2161872.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论