Now proceed to create a more useful
filter. In this lesson, we will create a simple "RGB Intensity Modulator"
filter that allows the user to control the relative intensities of the red,
green, and blue channels in an image.
If you are too impatient to type in the following examples by hand, just use cut-and-paste to transfer the code from this lesson into the source edit window. |
First, type the following in the
source edit window:
%ffp |
This informs the compiler that it
will be compiling a program written in the Filter Factory Plus (FF+) language.
FM can compile filter programs written in several different source languages, including the original Adobe Filter Factory (FF) language, the Filter Factory Wizard (FFW) language, the extended Filter Factory Plus (FF+) language, and the full FilterMeister language (FML). In general, FM can automatically determine which language to compile, but sometimes it can be fooled. It is good practice to tell FM explicitly which language to use by prefacing your code with "%RGB" (for Filter Factory code), "%FFW" (for Filter Factory Wizard code), "%FFP" (for Filter Factory Plus code), or "%FML" (for FilterMeister Language code). |
%ffp
ctl(0):"Red intensity"
|
%ffp
ctl(0):"Red intensity",range=(0,100)
|
Okay, the slider bars now work, but
the filter still doesn't do anything! We need to tell the compiler what
operations to perform on each channel. Add the following formulas to define
the result of the R (red), G (green), and B (blue) channels, respectively.
%ffp
ctl(0):"Red intensity",range=(0,100)
R:r*ctl(0)/100
|
For example, the formula R:r*ctl(0)/100 means: Take the value of the red pixel (r) in the input image, multiply it by the value of control 0, and divide the result by 100 (to convert the value of the control to a percentage). Assign the result to the corresponding red pixel in the output image (R).
%ffp
ctl(0):"Red intensity",range=(0,100),val=100
R:r*ctl(0)/100
|
Now for the next refinement. So far, the user can set each channel to a percentage of the original value between 0% and 100%. This allows the user to darken any given channel, but not to brighten it. We can give the user more control by allowing the user to amplify each channel beyond 100%. So let's change the range of each control to 0 through 200:
ctl(0):"Red intensity",range=(0,200),val=100 ctl(1):"Green intensity",range=(0,200),val=100 ctl(2):"Blue intensity",range=(0,200),val=100But remember that the intensity value of each channel pixel must lie in the range 0 to 255. What happens if we try to amplify the value of some pixel beyond 255? Will the pixel value "wrap" around to the low end of the range, thus actually *darkening* the pixel rather than brightening it? Yes, it will, which is probably not the desired behavior. A more acceptable solution is to "clamp" the value of a pixel to 255 if we try to increase it beyond 255. We could accomplish this, for example, by using the formula:
R:(r*ctl(0)/100 > 255) ? 255 : (r*ctl(0)/100)
R: | (r*ctl(0)/100 > 255) | ? 255 | : | (r*ctl(0)/100) |
Send the Result to the Red Pixel by solving for the following: | If the computed value is greater than 255 | set the result to 255 | otherwise | use the computed value itself |
This formula says: If the computed value is greater than 255, set the result to 255; otherwise, use the computed value itself.
However, this elaborate code is unnecessary!
FilterMeister automatically clamps output channel values to 255 (if the result
would exceed 255) or to 0 (if the result would be negative). So the only
code we need is:
%ffp
ctl(0):"Red intensity",range=(0,200),val=100
R:r*ctl(0)/100
|
Compile this code and verify that you can brighten each color channel without producing "dark" artifacts due to wraparound.
Now, for another refinement. Note that the formula for each channel is identical except for the name of the input pixel (r, g, or b) and the index of the corresponding control (0, 1, or 2).
Recall that the special variable 'c' means the same as 'r', 'g', or 'b', depending on which channel is being processed. Also remember that the variable 'z' is set to 0, 1, or 2 when the red, green, or blue channel, respectively, is being processed. So we can recode the channel formulas with identical expressions as follows:
R:c*ctl(z)/100 G:c*ctl(z)/100 B:c*ctl(z)/100
Finally, note that the FF+ language
allows you to specify a list of channels to the left of the colon (:), which
means that the formula on the right is to be used for each channel in the list
in turn (and in the designated order). So we can simplify our code further
to:
%ffp
ctl(0):"Red intensity",range=(0,200),val=100
R,G,B:c*ctl(z)/100 |
This may not seem like a big deal
here, but it can save a lot of typing (or cutting-and-pasting) when used with
more complex code.
Go to Step
4 - Customizing the Filter Dialog
Home | Download | Documents | Tips & Tutorials | Code Library | Help / User Group | Order