Accurately get a color from pixel on screen and convert its color space

ε祈祈猫儿з 提交于 2020-01-02 10:15:35

问题


I need to get a color from a pixel on the screen and convert its color space. The problem I have is that the color values are not the same when comparing the values against the Digital Color Meter app.

// 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))
}

My code (converted to sRGB): 255, 38, 0
Digital Color Meter (sRGB): 255, 4, 0

How do you get a color from a pixel on the screen with the correct color space values?


Update:

If you don’t convert the colors colorspace to anything (or convert it to calibratedRGB), the values match the Digital Color Meters values when it’s set to “Display native values”.

My code (not converted): 255, 0, 1
Digital Color Meter (set to: Display native values): 255, 0, 1

So why when the colors values match the native values in the DCM app, does converting the color to sRGB and comparing it to the DCM's values(in sRGB) not match? I also tried converting to other colorspaces and there always different from the DCM.


回答1:


OK, I can tell you how to fix it/match DCM, you'll have to decide if this is correct/a bug/etc.

It seems the color returned by colorAt() has the same component values as the bitmap's pixel but a different color space - rather than the original device color space it is a generic RGB one. We can "correct" this by building a color in the bitmap's space:

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)!

I think you'll find that the values of correctedColor track DCM's native values, and those of sRGBcolor track DCM's sRGB values.

Note that we are constructing a color in the device space, not converting a color to the device space.

HTH



来源:https://stackoverflow.com/questions/46961761/accurately-get-a-color-from-pixel-on-screen-and-convert-its-color-space

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!