我需要从屏幕上的像素中获取颜色并转换其颜色空间。我遇到的问题是,在将数值与Digital Color Meter应用程序进行比较时,颜色值并不相同。
// create a 1x1 image at the mouse position
if let image:CGImage = CGDisplayCreateImage(disID, rect: CGRect(x: x, y: y, width: 1, height: 1))
{
let bitmap = NSBitmapImageRep(cgImage: image)
// get the color from the bitmap and convert its colorspace to sRGB
var color = bitmap.colorAt(x: 0, y: 0)!
color = color.usingColorSpace(.sRGB)!
// print the RGB values
let red = color.redComponent, green = color.greenComponent, blue = color.blueComponent
print("r:", Int(red * 255), " g:", Int(green * 255), " b:", Int(blue * 255))
}
我的代码(转换为sRGB):255, 38, 0
数字色度计(sRGB):255, 4, 0
如何使用正确的色彩空间值从屏幕上的像素获取颜色?
更新:
如果不将颜色颜色空间转换为任何颜色空间(或将其转换为calibratedRGB),则当设置为“显示原生值”时,这些值与数字颜色计数器值匹配。
我的代码(未转换):255, 0, 1
数字色度计(设置为:显示原始值):255, 0, 1
那么为什么当颜色值与DCM应用中的原生值相匹配时,将颜色转换为sRGB并将其与DCM的值(在sRGB中)进行比较是不匹配的?我也尝试过转换到其他颜色空间,并且总是与DCM不同。
答案 0 :(得分:1)
好的,我可以告诉你如何解决它/匹配DCM,你必须决定这是否正确/错误等等。
似乎colorAt()
返回的颜色与位图的像素具有相同的组件值,但颜色空间不同 - 而不是原始设备颜色空间,它是一般的RGB颜色空间。我们可以纠正"这可以通过在位图的空间中构建颜色来实现:
let color = bitmap.colorAt(x: 0, y: 0)!
// need a pointer to a C-style array of CGFloat
let compCount = color.numberOfComponents
let comps = UnsafeMutablePointer<CGFloat>.allocate(capacity: compCount)
// get the components
color.getComponents(comps)
// construct a new color in the device/bitmap space with the same components
let correctedColor = NSColor(colorSpace: bitmap.colorSpace,
components: comps,
count: compCount)
// convert to sRGB
let sRGBcolor = correctedColor.usingColorSpace(.sRGB)!
我认为您会发现correctedColor
的值跟踪DCM的原生值,而sRGBcolor
跟踪DCM的sRGB值。
请注意,我们在设备空间中构建颜色,而不是将颜色转换为设备空间。
HTH