I have an Image View which displays an image and the CGPoint when the cursor is over the image. I am able to get and display the cursor position in pixels but cannot figure out how to get the value of the pixel rgb.
import SwiftUI
struct ImageView: View {
@State var location: CGPoint = .zero
@State var didHover = false
var body: some View {
VStack {
Text("Os três")
.font(.system(size: 16))
Image("Burros_1") // placeholder
.resizable()
.scaledToFit()
.aspectRatio(contentMode: .fit)
.background(Color.black.opacity(0.5))
.frame(width: 640, height: 480)
.border(.green)
.onHover { hover in
if hover {
NSCursor.crosshair.push()
} else {
NSCursor.pop()
}
}
.onContinuousHover { phase in // (col, row)
switch phase {
case .active(let location):
NSCursor.crosshair.push()
self.location = location // WORKS
self.didHover = true
case .ended:
self.didHover = false
break
}
}
// GOAT add DN
let rowString = String(format: "%03d", Int(round(location.x)))
let colString = String(format: "%03d", Int(round(location.y)))
if didHover { // Missing pixel value GOAT
Text("(r, c, DN) \(rowString), \(colString), ??")
.monospaced()
}
else { // this conserves a line for the Text
Text(" ")
}
} // VStack
} //
}
I've searched on-line, including stack overflow, extensively but most results are for iOS, not macOS, and don't really address my problem or won't compile. I've also 'jumped' to definitions to try to spot a method but no luck.
You could try this approach using NSBitmapImageRep
, to get the pixel rgb.
Example code:
struct ContentView: View {
var body: some View {
ImageView()
}
}
struct ImageView: View {
let nsimg = NSImage(named: "mycat")!
@State private var location: CGPoint = .zero
@State private var pixelColor: NSColor?
var body: some View {
VStack {
Text("location: \(location.debugDescription)")
Text("color: \(pixelColor?.debugDescription ?? "no color")")
GeometryReader { geo in
Image(nsImage: nsimg)
.resizable()
.frame(width: 640, height: 480)
.onContinuousHover { phase in
switch phase {
case .active(let location):
NSCursor.crosshair.push()
self.location = location
// todo convert coords using GeometryReader
pixelColor = nsimg.colorAt(location)
case .ended:
break
}
}
.border(.green)
}
}
.onAppear {
pixelColor = nsimg.colorAt(CGPoint(x: 20, y: 60)) // for testing
print("---> pixelColor: \(pixelColor)")
}
}
}
extension NSImage {
func colorAt(_ pos: CGPoint) -> NSColor? {
let imageRep = NSBitmapImageRep(data: self.tiffRepresentation!)
return imageRep?.colorAt(x: Int(pos.x), y: Int(pos.y))
}
}