准确地从屏幕上的像素获取颜色并转换其颜色空间

时间:2017-10-26 18:50:05

标签: swift macos cocoa colors

我需要从屏幕上的像素中获取颜色并转换其颜色空间。我遇到的问题是,在将数值与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不同。

1 个答案:

答案 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