by Kevin Goldsmith


October 17, 2007

So, I promised a walk through tutorial of the code I wrote in our MAX talk. It’s taken me a while to get some time, but here I go.

So the filter I’m going to write works like this: I want to take a color image and then fade it to black and while and then continue to fade into a sepia-tone. Sort of a Ken Burns-ish thing. I’m going to walk through how I would do this iteratively, starting from the default new filter you get by choosing “New Filter” and then expand on it until I get my final goal.

To Illustrate

we’ll create a filter that goes smoothly from this:
start image

To This:
middle image

And finally to this:
end image

Step One: The Blank Slate

In the AIF Toolkit, load up an image by choosing Load Image File 1 in the File Menu. Then choose New Hydra Filter also from the File menu. In the editor, you see something very much like this:

kernel NewFilter{voidevaluatePixel(in image4 src, out pixel4 dst){dst = sampleNearest(src,outCoord());}}

We’ll deconstruct this a bit. The first part

kernel NewFilter

Is the information about the kernel. The kernel is the filter. We have the name of the kernel and some metadata about it. The metadata will be used by applications that run the kernel to help identify it.This part:

voidevaluatePixel(in image4 src, out pixel4 dst){dst = sampleNearest(src,outCoord());}

is where the action happens. The evaluatePixel method runs on every pixel of the image to produce the output. The evaluatePixel method can take from zero up to four images as input. In this case, we are only using one image as input. The dst variable is the output of the method and an output is required since a filter wouldn’t make any sense without an output! Inside the method, we are assigning the output pixel to be a sample from the input image at the coordinate of the output image we are processing.Now, let us be sure that we are working in a flash-compatible way. Under the build menu, select Turn on Flash Warnings And Errors. This will make sure that if we do something that won’t work in Flash, we’ll know about it.To see where we are, we’ll run the filter. Click on the Run button underneath the editor. You should see nothing change in your image, because we haven’t done anything yet, but it’s a good practice when you are editing to click that run button a lot to check your changes.

Part Two: Changing the metadata

Let’s start our filter by doing some housekeeping. Fixing up the kernel metadata is a good first step. I’m going to type some non-default-ish text into the metadata which will help me know the difference between filters and later should let the tools be able to identify your filter. I’m going to change the nameSpace, vendor, version and description metadata.

kernel FadeToHistory{voidevaluatePixel(in image4 src, out pixel4 dst){dst = sampleNearest(src,outCoord());}}

We should run again to make sure there isn’t any syntax errors. Now is also a good time to Save our work.

Part Three: Doing something interesting

A good next step would be getting some simple black and white going. The cheapest way to do this would be to just grab one of the color channels and use that for all three colors (this will look really bad on some images, but it will ok on most photographs). We’re going to use something tricky from the Hydra language to do this easily:

kernel FadeToHistory{voidevaluatePixel(in image4 src, out pixel4 dst){dst = sampleNearest(src,outCoord()).rrra;}}

The cool and important line here is dst = sampleNearest(src,outCoord()).rrra;This tells the Hydra compiler to use the red chanel from from the input image for the red, green and blue channels of the output image, and to pass through the alpha channel to the output image.When we run this, we get:cheapbw.jpg
which is ok, but we can do better. I’ll show you how in the next installment.If you are playing along at home, here is the Hydra file for what we have so far: Download fileOther parts to this tutorial:Parts 4 – 6