0

I have to generate an image like the one in Apples Doc at CIRadialGradient found here:

CIRadialGradient

I tried many ways and ended with:

+(NSImage*)radialGradientWithR0:(float)r0 r1:(float)r1 c0:(NSColor*)c0 c1:(NSColor*)c1 imageDimensionPx:(int)imageDimension
{
    CIColor* cc0 = [[CIColor alloc]initWithColor:c0];
    CIColor* cc1 = [[CIColor alloc]initWithColor:c1];
    CIVector* civ = [CIVector vectorWithX:imageDimension/2 Y:imageDimension/2];

    CIFilter* filter = [CIFilter filterWithName:@"CIRadialGradient"];
    [filter setDefaults];
    [filter setValue:civ forKey:@"inputCenter"];
    [filter setValue:[NSNumber numberWithFloat:r0] forKey:@"inputRadius0"];
    [filter setValue:[NSNumber numberWithFloat:r0] forKey:@"inputRadius1"];
    [filter setValue:cc0 forKey:@"inputColor0"];
    [filter setValue:cc1 forKey:@"inputColor1"];

    CIImage* outputImage = [filter valueForKey:@"outputImage"];

    NSRect outputImageRect = NSRectFromCGRect([outputImage extent]);
    NSImage* blurredImage = [[NSImage alloc]
                             initWithSize:NSMakeSize(imageDimension,  imageDimension)];

    [blurredImage lockFocus];
    [blurredImage drawAtPoint:NSZeroPoint fromRect:NSMakeRect(0, 0, imageDimension, imageDimension) operation:NSCompositeSourceOver fraction:1.0];
    [blurredImage unlockFocus];

    return blurredImage;
}

but all I can get is an empty image.

Please help me.

Thanks

Felix

Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
Felix
  • 63
  • 5

1 Answers1

2

There are several errors in you code that prevent it from working:

  • typo in the arguments: r1 is not used in the second call

You need to change the second line:

 [filter setValue:[NSNumber numberWithFloat:r0] forKey:@"inputRadius0"];
 [filter setValue:[NSNumber numberWithFloat:r0] forKey:@"inputRadius1"];
  • you don't need this: NSRect outputImageRect = NSRectFromCGRect([outputImage extent]);

  • [blurredImage lockFocus]; followed by [blurredImage drawAtPoint: basically means something like: draw the image in itself. You meant: [outputImage drawAtPoint:..]

Here is a method that does what you want:

-(NSImage *) radialGradientWithR0:(float)r0 r1:(float)r1 c0:(NSColor*)c0 c1:(NSColor*)c1 imageDimensionPx:(int)imageDimension {

    CIColor* cc0 = [[CIColor alloc]initWithColor:c0];
    CIColor* cc1 = [[CIColor alloc]initWithColor:c1];
    CIVector* civ = [CIVector vectorWithX:imageDimension/2 Y:imageDimension/2];

    CIFilter* filter = [CIFilter filterWithName:@"CIRadialGradient"];

    [filter setValue:civ forKey:@"inputCenter"];
    [filter setValue:[NSNumber numberWithFloat:r0] forKey:@"inputRadius0"];
    [filter setValue:[NSNumber numberWithFloat:r1] forKey:@"inputRadius1"];
    [filter setValue:cc0 forKey:@"inputColor0"];
    [filter setValue:cc1 forKey:@"inputColor1"];

    NSImage * res = [[NSImage alloc] initWithSize:NSMakeSize(imageDimension, imageDimension)];
    [res lockFocus];
    [[filter valueForKey:@"outputImage"]
     drawAtPoint:NSZeroPoint 
     fromRect:NSMakeRect(0, 0, imageDimension, imageDimension)                   
     operation:NSCompositeDestinationAtop  fraction:1.0];
    [res unlockFocus];
    return res;
}

An NSImageWell displaying the radial gradient

alecail
  • 3,993
  • 4
  • 33
  • 52