Color matching of NSBitmapImageRep
Color matching of NSBitmapImageRep
- Subject: Color matching of NSBitmapImageRep
- From: Wim Lewis <email@hidden>
- Date: Wed, 29 Aug 2007 17:54:07 -0700
I've been trying to track down some unexpected color shifts in a
supposedly color-sync'd application. I've discovered that
NSBitmapImageRep is not rendering its colors at all in the way that I
expect. It seems to be using a different color profile than the one I
tell it to. Can anyone tell me how to get a bitmap to draw color-
matched?
As an example, let's say that I have an NSColor (or CGColorSpaceRef +
components, but that's by the way). I want to set some pixels of an
NSBitmapImageRep to that same color, so that when I draw them side-by-
side they render as the same color on the screen.
What I'm doing is this:
- Convert the color to the calibrated RGB space by calling [foo
colorUsingColorSpaceName:NSCalibratedRGBColorSpace].
- Create an NSBitmapImageRep in the NSCalibratedRGBColorSpace, 32-bit
RGBA:
NSBitmapImageRep *foo = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:buffer
pixelsWide:width pixelsHigh:height
bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES isPlanar:NO
colorSpaceName:NSCalibratedRGBColorSpace
bytesPerRow:4 * width bitsPerPixel:32];
- Extract the color's components using -redComponent, etc.; or -
getComponents:, or -getRed:green:blue:alpha:. (These all produce the
same numbers anyway).
- Set the color on a pixel (or all the pixels) by scaling them to
[0..255] and stuffing them into 'buffer'.
This produces a color which is almost, but not quite, the same as the
color I started with. It's not a matter of converting to integer
values incorrectly --- for one thing, the error is more than +/- 1
per component; and for another, I can use NSBitmapImageRep's -
setColor:atX:xy: method and get exactly the same results as if I'd
done the conversion myself.
The color shift has the look that mismatched profiles tend to; it's
more apparent towards some corners of the gamut, and invisible in
other areas.
Interestingly, if I draw into the bitmap image rep by creating a
context using -graphicsContextWithBitmapImageRep: and setting the
color on that context and filling a rectangle, then the bitmap will
draw with the desired color. But if I examine the bitmap I create in
that way, its color components are not the same as the original color!
For example, if I start with [NSCalibratedRGBColorSpace 0 0.905991 1
1] (a sort of teal color), I can convert it to (0, 231, 255) and
stuff that into the bitmap data, or I can use -setColor:atX:y:, which
also results in the values (0, 231, 255) in the buffer.
But if I draw the color into the bitmap via a graphics context, then
the buffer shows the triple (23, 225, 254), and -colorAtX:y: returns
the color [NSCalibratedRGBColorSpace 0.0901961 0.882353 0.996078 1].
The bizarre thing is that it is this altered value which draws
correctly.
For other colors, the shift is much smaller. For example, the color
triplet (255, 0, 114) maps to the triplet (255, 2, 115) when drawn.
So, what I wonder is:
- Why isn't the NSBitmapImageRep rendering its contents in the
color space I ask it to?
- What color space *is* it using?
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden