Thank to all those who tried to help me with my problem.

My gradient color problem is just a simplified version of what I have to do. I need to do a scientific simulation where I have to set the color of random pixels to a given color which corresponds to a value inside a given range. So I really need to compute the gradient color and set each pixel separately.

Thanks to Eddie Herbert, I was not aware of the existence of the blend function in the NSColor class.

Finally, I could locate the problem to reside in the NSBitmapImageRep setColor:atX:y: method. If I understand this method correctly, it is supposed to do something like this (if the color space of the image rep and the provided color are the same):

-(void)setColor:(NSColor*)color atX:(NSInteger)x y:(NSInteger)y
{
   CGFloat comps[5];
   [color getComponents:comps];
NSInteger i;
   NSUInteger intComps[5];
   for (i = 0; i < [self samplesPerPixel]; i++)
   {
       intComps[i] = comps[i] * 255;
   }
[self setPixel:intComps atX:x y:y];

}


Using this method instead of the one provided by the original NSBitmapImageRep, the image gets rendered as expected.

I am not understanding correctly the setColor:atX:y: class or it is a bug... I would be glad to have an advise whether to file a bug report or not (I have never done this).

Thanks again for your help !


Cheers,
Christian Kaiser








Jean-Daniel Dupas wrote:
Don't know why you got this problem, but if I had to fill a bitmap using a simple gradient, i would probably use either CGGradient (Leopard required) or CGShading (if you want a greater control of the shading function, etc...).

It can be done like this:

NSGraphicsContext *ctxt = [NSGraphicsContext graphicsContextWithBitmapImageRep:imageRep]; /* see doc for details about bitmap format supported */
CGContextRef cgctxt = [ctxt graphicPort];
CGShadingRef shading = CGShadingCreate(...); /* see Quartz 2D programming guide */
CGContextDrawShading(cgctxt, shading);
CGShadingRelease(shading);

This will be really faster than creating a NSColor object for each pixel.

In the same way, you can fill it with an uniform color using CGContextFillRect() function.

And is you want to use Cocoa drawing function instead, set your new context as the current context using -[NSGraphicsContext setCurrentContext:] and the you will be able to call NSBezierPath function for example.


Le 31 mars 08 à 21:30, Christian Kaiser a écrit :
I'm struggling with setting color in a NSBitmapImageRep. I'm computing the components of a NSColor according to a numeric value; its basically a linear interpolation between all components of two NSColors. I've got a function which is computing the new NSColor based on a given value. If I call this function repeatedly using the same value and setting the color using NSBitmapImageRep setColor:atX:y:, I expect to have a uniform image if applying to all pixels. But this is not the case...! What am I missing ?

As I'm probably a little bit confusing, here the code producing my strange image :



  // Creating two colors which define a gradient. The color for our image
  // will be computed using this gradient.

  NSColor *lightYellow =
[NSColor colorWithCalibratedRed:0.97 green:0.93 blue:0.65 alpha:1.0];
    NSColor *darkRed =
[NSColor colorWithCalibratedRed:0.69 green:0.09 blue:0.11 alpha:1.0];


  // Creating an empty image with the same color space.

  NSBitmapImageRep *img = [[NSBitmapImageRep alloc]
      initWithBitmapDataPlanes:NULL
      pixelsWide:10
      pixelsHigh:10
      bitsPerSample:8
      samplesPerPixel:3
      hasAlpha:NO
      isPlanar:YES
      colorSpaceName:[lightYellow colorSpaceName]
      bitmapFormat:0
      bytesPerRow:0
      bitsPerPixel:0];
// Assigning the same (???) color to all pixels.
  int x, y;
  for (y = 0; y < 10; y++)
  {
      for (x = 0; x < 10; x++)
      {
          NSColor *imgColor = [GradientColor gradientColorWithValue:40.0
              minColor:lightYellow maxColor:darkRed
              minValue:30.0 maxValue:60.0];
                    [img setColor:imgColor atX:x y:y];
      }
  }
      [[img TIFFRepresentation]
      writeToFile:@"/Users/chkaiser/Desktop/img.tif" atomically:YES];


And the function computing the gradient color based on our values:

+(NSColor*)gradientColorWithValue:(double)value minColor:(NSColor*)c1
  maxColor:(NSColor*)c2 minValue:(double)v1 maxValue:(double)v2
{
    // Color components.
  CGFloat comps1[5];
  [c1 getComponents:comps1];
  CGFloat comps2[5];
  [c2 getComponents:comps2];
    // Compute the multiplication factor for the value. This factor has
  // a value between 0 and 1.
  double factor = (value - v1) / (v2 - v1);
    // Compute the new components.
  int i;
  CGFloat newComps[5];
  for (i = 0; i < [c1 numberOfComponents]; i++)
  {
      newComps[i] =
          (factor * (comps2[i] - comps1[i])) +
              comps1[i];
  }
    // Create the new color with the computed components.
  NSColor *newColor = [NSColor colorWithColorSpace:[c1 colorSpace]
      components:newComps count:[c1 numberOfComponents]];
    return newColor;
 }


What is going wrong here ?

I have not found any similar topic on this list until now, even if it seems to me quite strange. Is there something obvious I am missing ?

--Christian Kaiser


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to