Re: Problem with setting color in NSBitmapImageRep
Re: Problem with setting color in NSBitmapImageRep
- Subject: Re: Problem with setting color in NSBitmapImageRep
- From: Christian Kaiser <email@hidden>
- Date: Thu, 03 Apr 2008 21:14:15 +0200
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 (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