문제

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!

도움이 되었습니까?

해결책

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top