views:

381

answers:

1

Im trying to draw specific colour rectangles into a CGBitmapContext and then later compare pixel values with the colour i drew (a kind of hit-testing).

On Leopard this works fine but on SnowLeopard the pixel-values i get out are different to the colour values i draw in - i guess due to colorspace confusion and ignorance on my part.

The basic steps i take are:-

  1. create a bitmap context with a kCGColorSpaceGenericRGB colorspace
  2. set the context's fillColorSpace to the same kCGColorSpaceGenericRGB colorspace
  3. set the context's fill color
  4. draw
  5. get the bitmapContextData, iterate pixel values, etc.

As an example, on Leopard if i do:-

CGContextSetRGBFillColor(cntxt, 1.0, 0.0, 0.0, 1.0 ); // set pure red fill colour
CGContextFillRect(cntxt, cntxtBounds); // fill entire context

each pixel has a value UInt8 red==255, green==0, blue==0, alpha==255

On Snow Lepard however, each pixel has a value UInt8 red==243, green==31, blue==6, alpha==255 (These values are made up - i'm not on snow leopard right now. They are roughly typical of what i was getting - still definitely 'Red' but difficult for me to correlate with (1.0,0,0). Similar for other colours too except (1.0,1.0,1.0) would be exactly (255,255,255) and (0,0,0) would be exactly (0,0,0) ).

I have tried other colorSpaces but a similar thing happens. Any help or pointers is much appreciated, thanks.

UPDATE I believe this demonstrates what i'm on about..

//create
NSUInteger arbitraryPixSize = 10;
size_t components = 4;
size_t bitsPerComponent = 8;
size_t bytesPerRow = (arbitraryPixSize * bitsPerComponent * components + 7)/8;
size_t dataLength = bytesPerRow * arbitraryPixSize;
UInt32 *bitmap = malloc( dataLength );
memset( bitmap, 0, dataLength );

CGColorSpaceRef colSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);

CGContextRef context = CGBitmapContextCreate (             bitmap, arbitraryPixSize, arbitraryPixSize,              bitsPerComponent,bytesPerRow,             colSpace, kCGImageAlphaPremultipliedFirst );

CGContextSetFillColorSpace( context, colSpace );
CGContextSetStrokeColorSpace( context, colSpace );

// -- draw something
CGContextSetRGBFillColor( context, 1.0f, 0.0f, 0.0f, 1.0f );
CGContextFillRect( context, CGRectMake( 0, 0, arbitraryPixSize, arbitraryPixSize ) );

// test the first pixel
UInt8 *baseAddr = (UInt8 *)CGBitmapContextGetData(context);
UInt8 alpha = baseAddr[0];
UInt8 red = baseAddr[1];
UInt8 green = baseAddr[2];
UInt8 blue = baseAddr[3];

CGContextRelease(context);
CGColorSpaceRelease(colSpace);

RESULTS

Leopard -> red==255, green==0, blue==0, alpha==255

Snow leopard -> red==228, green==29, blue==29, alpha==255

+1  A: 

Take a look at the docs for CGContextSetRGBFillColor.

CGContextSetRGBFillColor Sets the current fill color to a value in the DeviceRGB color space.

You wanted your components to be with respect to the generic RGB space. So, use one of the other methods of setting the fill color.

Ken
thanks, so just for the record i used CGColorRef redCol = CGColorCreateGenericRGB( 1.0f, 0.0f, 0.0f, 1.0f ); CGContextSetFillColorWithColor( context, redCol );
jib: Don't forget to release `redCol` with `CFRelease` or `CGColorRelease`.
Peter Hosey