Ever since Gus Mueller released Acorn, I was itching to write a few plug-ins for it - having an image editor with scripting capabilities is a rather exciting prospect for me.

Acorn Plugins
ImageUnit for Reflections and a Spotlight!

The first thing I tried out was simply running a filter kernel. Strangely enough, Apple’s documentation in that area is rather lacking - the assumption is always that you want to build the whole filter infrastructure with your kernel. Which I don’t - I want to get things going as soon as possible.

Well, after a bit of fiddling, here’s the necessary Python code:

kernelCode = """
kernel vec4 test(sampler src)
{
    return sample(src,samplerCoord(src))*0.5;
}
"""

def main(image):

    kernels = CIKernel.kernelsWithString_( kernelCode )
    kernel = kernels.objectAtIndex_(0)
    sampler = CISampler.samplerWithImage_( image )
    filter = CIFilter.alloc().init()

    return filter.apply_arguments_options_(kernel,[sampler,None],None)  

As an additional caveat, if you use Acorn versions older than 1.0.3, you need to attach a crop filter so the resulting image has extents. (Gus has added a fix for that in later releases)

extent = image.extent()

image = filter.apply_arguments_options_(kernel,[sampler,None],None)

# This part can be skipped with the latest Acorn - Gus added a fix. (Thanks, Gus!)
theCropVector = CIVector.vectorWithX_Y_Z_W_(0.0, 0.0, extent[1][0], extent[1][1])
cropFilter = CIFilter.filterWithName_(”CICrop”)
cropFilter.setValue_forKey_(theCropVector, “inputRectangle”)
cropFilter.setValue_forKey_(image, “inputImage”)
return cropFilter.valueForKey_(”outputImage”)

This gives you tremendous power, since it allows you to create ad-hoc filter effects - and all you have to do is change the python code on disc. Acorn will automatically use the latest version.

The only drawback here is that it’s hard to control filter parameters in a plug-in. You could write lots of U/I code - and you could do that in Python, yes - but Acorn already has a pretty fancy interface to filters. So instead, we’d like to register a core image filter via Plugins.

Can we do that? Technically, yes. PyObjC lets us subclass Objective C classes. Unfortunately, Python plugins get executed after the list of Core Image Filters is built - so our own filter will never show up in the filter menu. (The same is true for Objective-C Acorn plugins)

So - at least until Gus changes that - I’ll publish my filter kernels as Image Unit in Objective C. It’s a pain to create, compared to just wielding Python, though. (Technically, I could probably use the CGenericFilter in Jonathan Wights ToxicMedia framework. Haven’t gotten around to it yet. Please let me know if you try.)

I’d bug Gus about that, but I’ll wait till I can actually afford a license. I’ve soaked up quite a bit of his time already, and all on the trial version. Thank you for all the support, Gus - and I’ll be back ;)

And because I’ve had so much fun developing filter kernels, here’s a Core Image plugin with the spotlight and reflection effect I used further up. Just drop it into ~/Library/Graphics/Image Units, and you have those two filters in the ‘Stylize’ category.

Update: Full source for Acorn Python plugin

Leave a reply