Reputation: 16256
I am developing an OS X app that uses custom Core Image filters to attain a particular effect: Set one image's luminance as another image's alpha channel. There are filters to use an image as a mask for another but they require a third -background- image; I need to output an image with transparent parts, no background set.
As explained in Apple's documentation, I wrote the kernel code and tested it in QuartzComposer; it works as expected.
The kernel code is:
kernel vec4 setMask(sampler src, sampler mask)
{
vec4 color = sample(src, samplerCoord(src));
vec4 alpha = sample(mask, samplerCoord(mask));
color.a = alpha.r;
// (mask image is grayscale; any channel colour will do)
return color;
}
But when I try to use the filter from my code (either packaging it as an image unit or directly from the app source), the output image turns out to have the following 'undefined'(?) extent:
extent CGRect origin=(x=-8.988465674311579E+307, y=-8.988465674311579E+307) size=(width=1.797693134862316E+308, height=1.797693134862316E+308)
and further processing (convert to NSImage bitmap representation, write to file, etc.) fails. The filter itself loads perfectly (not nil) and the output image it produces isn't nil either, just has an invalid rect.
EDIT: Also, I copied the exported image unit (plugin), to both /Library/Graphics/Image Units
and ~/Library/Graphics/Image Units
, so that it appears in QuartzComposer's Patch Library, but when I connect it to the source images and Billboard renderer, nothing is drawn (transparent background).
Am I missing something?
EDIT: Looks like I assumed to much about the default behaviour of -[CIFilter apply:]
.
My filter subclass code's -outputImage
implementation was this:
- (CIImage*) outputImage
{
CISampler* src = [CISampler samplerWithImage:inputImage];
CISampler* mask = [CISampler samplerWithImage:inputMaskImage];
return [self apply:setMaskKernel, src, mask, nil];
}
So I tried and changed it to this:
- (CIImage*) outputImage
{
CISampler* src = [CISampler samplerWithImage:inputImage];
CISampler* mask = [CISampler samplerWithImage:inputMaskImage];
CGRect extent = [inputImage extent];
NSDictionary* options = @{ kCIApplyOptionExtent: @[@(extent.origin.x),
@(extent.origin.y),
@(extent.size.width),
@(extent.size.height)],
kCIApplyOptionDefinition: @[@(extent.origin.x),
@(extent.origin.y),
@(extent.size.width),
@(extent.size.height)]
};
return [self apply:setMaskKernel arguments:@[src, mask] options:options];
}
...and now it works!
Upvotes: 1
Views: 606
Reputation: 2916
How are you drawing it? And what does your CIFilter
code look like? You'll need to provide a kCIApplyOptionDefinition
most likely when you call apply: in outputImage
.
Alternatively, you can also change how you are drawing the image, using CIContext
's drawImage:inRect:fromRect
.
Upvotes: 1