I am going to post this here in hopes that others who have had this issue can find it easily. I spent many many hours today fiddling with custom image units (ie CIFilters) and this one stumped me for quite some time.
OK, here is the thing. If you follow apple’s (generally very good) tutorial on creating custom filters, you g through this rough timeline:
1) total confusion.. what the hell is this kernal thing?
2) general understanding .. ahh haa!
3) coding .. this is so EASY! it is great!
4) validating .. WTF?
5) fiddling and finding all the syntax errors by hand in your kernal
6) validating: PASS! yay!
7) loading into QC for testing.. this is soo exciting!!!
8) Cannot Render: Bounds: Infinite (must crop to render).. WTF?!?!
9) spiral into deep deep dark place because after many hours of scouring the docs you still cannot figure out how in the name of Zues’s BUTTHOLE do you get a nice filter like ALL THE REST that render without cropping!!
so, here is the solution:
After many hours of looking for clues (and spending an inordinate amount of time trying to figure out how the ROI had to do with the output extent (hint, it doesnt) i stumbled across the fact that you can pass extra info to the kernel via three special kernel keys:
kCIApplyOptionExtent, kCIApplyOptionDefinition, and kCIApplyOptionUserInfo.
the one that we care about for today is kCIApplyOptionExtent. and you use it like so:
in your – (CIImage *)outputImage method:
NSArray * outputExtent = [NSArray arrayWithObjects: [NSNumber numberWithInt:0], [NSNumber numberWithInt:0], [NSNumber numberWithFloat:[inputImage extent].size.width], [NSNumber numberWithFloat:[inputImage extent].size.height],nil]; return [self apply:_BBSubtractionCompositeFilterKernel, src, bg, kCIApplyOptionExtent, outputExtent, nil];
and that is it. that will set the output extent to be the same as the inputImage extent. You can, of course set it to whatever you want, but i imagine the general case is that you want to get out something just as big as you sent in.
I hope this helps someone!