Legal
The views expressed in this blog are my own and do not necessarily reflect the views of Adobe Systems Incorporated.
Search
October 17, 2007
Writing a FadeToHistory Hydra Filter, part 1
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:

To This:

And finally to this:

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
< nameSpace : "your namespace";
vendor : "your vendor";
version : 1;
description : "your description";
>
{
void
evaluatePixel(in image4 src, out pixel4 dst)
{
dst = sampleNearest(src,outCoord());
}
}
We'll deconstruct this a bit. The first part
kernel NewFilter
< nameSpace : "your namespace";
vendor : "your vendor";
version : 1;
description : "your description";
>
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:
void
evaluatePixel(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
< nameSpace : "Kevin's Tutorial Filters";
vendor : "Kevin's Filters, Inc";
version : 1;
description : "Fade from color to B&W to sepia";
>
{
void
evaluatePixel(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
< nameSpace : "Kevin's Tutorial Filters";
vendor : "Kevin's Filters, Inc";
version : 1;
description : "Fade from color to B&W to sepia";
>
{
void
evaluatePixel(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:

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 file
Other parts to this tutorial:
Parts 4 - 6
Trackbacks
TrackBack URL for this entry:
http://blogs.adobe.com/cgi-bin/mt-tb.cgi/641
Comments
Thank you for signing in, You may now comment. (Sign Out)
(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)