Nova Design Logo


Main
Tutorials - Main
IFXCurrents - Main
ifx currents banner

Tutorials for ImageFX for the Amiga



All contents are Copyright - 1999, 2000 by Nova Design, Inc. All rights reserved. These documents may not be reproduced by any means without the express, written, permission of Nova Design, Inc.

Copyright - 1999, 2000 by Nova Design, Inc.

It is often helpful to hear what other users are doing with an application. If you would like to ask other ImageFX users about techniques and uses of ImageFX you can subscribe to Nova Design's ImageFX mailing list by going HERE and following the "Membership/Subscribe" link.

The ImageFX Currents Tutorials have been put into this HTML archive by the following individuals (Listed in alphabetical order):

  • Wil Haslup
  • John Whiting
  • Kermit Woodall

Logo illustration by Kermit Woodall
Edited by John A. Whiting
HTML coded by Wil Haslup and John A. Whiting
Screencaptures by Dave Matthews


ImageFX Tutorial: Part 2
Peeking Inside AutoFX


By Dave Matthews

This time, we're going to open the magic box and look inside. Warning, computer programming ahead! While Arexx scripts (the language via which AutoFX performs its magic) are reasonably straight forward, if you shudder at the mere thought of looking at source code, than you probably won't like this article. The easiest way to get into Arexx programming for ImageFX is to study other peoples scripts. ImageFX comes with about a million scripts for many effects, so be sure and look them over before you plunge into programming from scratch. In fact, as you can see by the copyright notice in the script, that is how I am learning.

OK, as you remember from last time, AutoFX is ImageFX's new visual batch processor system.Batch operations are built by adding images and Arexx commands via the interface, which then creates and executes these scripts, using the list of images you provided.

Actually, many of these AutoFX scripts are composed of three separate files. The command itself, and command.pre and command.post siblings. The .pre file is used for settings up things before you begin the actual command, and the .post is for cleaning up afterward. More one these later.

Figure 1
Figure 1: Our Batch script in AutoFX

Remember from last issue, Figure 1. This shows the list of filenames in the upper right window, and the list of commands in the lower right. Lets take a closer look at those commands. The First command, Load.ifx, is listed below (you can load this into a text editor if you like, it lives in the ImageFX3:Rexx/Autofx drawer. Just be sure not to accidently change it.:

/*
 * $VER: Load.ifx 2.6 (24.04.96)
 * Copyright © 1992-1996 Nova Design, Inc.
 * Originally written by Steve Tibbett
 * Updated by Thomas Krehbiel
 *
 * Loads main, swap, and alpha buffers.  Only loads the images if
 * they are specified.
 *
 * Inputs:
 *    Word(Arg(1),1) = Frame number (1 - N)
 *    Word(Arg(1),2) = Main filename ("-" if not specified)
 *    Word(Arg(1),3) = Swap filename ("-" if not specified)
 *    Word(Arg(1),4) = Sequence number (?)
 *    Word(Arg(1),5) = Total number of frames (N)
 *    Word(Arg(1),6) = Alpha filename ("-" if not specified) [2.6]
 *
 * Returns:
 *    0 if successful, non-zero on failure
 *
 */

OPTIONS RESULTS

/*
 * AutoFX 2.6 now sets some clip variables.  If we find them, use them instead
 * of the arg strings so that we can handle filenames with spaces in them.
 */

MainName = GETCLIP('AUTOFX_MAIN')
IF MainName = "" THEN MainName=word(Arg(1),2)

SwapName = GETCLIP('AUTOFX_SWAP')
IF SwapName = "" THEN SwapName=word(Arg(1),3)

AlfName = GETCLIP('AUTOFX_ALPHA')
IF AlfName = "" THEN AlfName=word(Arg(1),6)

LoadBuffer Force '"'MainName'"'
IF rc ~= 0 THEN EXIT rc

IF (SwapName ~= "-") THEN DO
        Swap
        LoadBuffer Force '"'SwapName'"'
        IF rc ~= 0 THEN EXIT rc
        Swap
        END

IF (AlfName ~= "-") /*&& (AlfName ~= "")*/ THEN DO
   LoadAlpha '"'AlfName'"' Force
   IF rc ~= 0 THEN EXIT rc
   END

EXIT 0

/* End Load.ifx ---------------------------------------------------------------------------*/

The Load command causes ImageFX to Load a picture into the main buffer. If they are specified, pictures will be loaded into the Swap buffer and the Alpha channel as well. While the above script, the insides of the Load command, looks complicated, it's really not. There are only a few things we need to worry about. First, Everything between /* and */ is a comment, just some notes about the script, who wrote it, what it does etc. These lines don't affect the program, but are there for humans to read. Always start your Arexx script with a comment line. This is good Karma, and anyway, Arexx won't run the script without it.

The OPTIONS RESULTS line is important if you want useful results from your Arexx program. This will allow values and the results of calculations and such to be used by the scripts and sent to ImageFX to act on.

The next groups of commands are more interesting, Look at the line that starts at:

MainName = GETCLIP('AUTOFX_MAIN')

Here is where the names that you added to the AutoFX GUI are collected, one at a time. MainName holds the name of the file meant for the main buffer, SwapName for the swap buffer and the whimsical AlfName holds the Alpha Channel filename.

The next Line is the heart of the matter:

LoadBuffer Force '"'MainName'"'

This command hands ImageFX a filename, with instructions to "Load this Picture". The Word Force tells IMageFX not to pop up a requester asking us if we're really, really sure we want to do this thing? Notice the Single and double quote marks? When the script sends ImageFX the filename, it encloses it in Double quotes, so ImageFX can handle a filename with a space in it. But doubles quotes have meaning to Arexx, so you need to enclose the double quotes with single quotes to let Arexx know these double quotes are to be sent out as is, not internally operated on.

Notice the following line:

IF rc ~= 0 THEN EXIT rc

This line checks the result code of loading the image. If something bad happened, file not found, corrupt image, or what have you, Arexx sets the rc variable to a non zero value. The above line checks the rc value and if it's not zero, something went wrong and Autofx gives up.

The rest of the lines ask if the swap and Alpha channel exist, and if so, loads them into the appropriate buffer. If all went well, then the final line:

EXIT 0

Tells AutoFX this command is finished, and we're ready to go on the next one, which is:

/* Begin Render_Amiga.ifx -----------------------------------------------------------*/


/*
 * Render_Amiga.ifx
 * Written by Thomas Krehbiel
 *
 * Render to an Amiga display format.
 *
 * Inputs:
 *    Word(Arg(1),1) = Frame number (1 - N)
 *    Word(Arg(1),2) = Main filename ("-" if not specified)
 *    Word(Arg(1),3) = Swap filename ("-" if not specified)
 *    Word(Arg(1),4) = Sequence number
 *    Word(Arg(1),5) = Total number of frames (N)
 *
 * Returns:
 *    0 if successful, non-zero on failure
 *
 */

OPTIONS RESULTS

base  = 'Autofx_RendAmiga_'

lockpal  = GETCLIP(base||'LockPal')

framenum = Word(Arg(1),1)
mainname = Word(Arg(1),2)
swapname = Word(Arg(1),3)
seqnum   = Word(Arg(1),4)
framemax = Word(Arg(1),5)

/* gracefully exit if no buffer */
GetMain
IF rc ~= 0 THEN EXIT 0

IF lockpal THEN DO
   IF framenum = 1 THEN
      LockRange 0 OFF
   ELSE
      LockRange 0 ON
   END
ELSE
   LockRange 0 OFF

Render Go

EXIT

/* End Render_Amiga.ifx ---------------------------------------------------------------------------*/

In this script, the line, base = 'Autofx_RendAmiga_' is a pointer to the routine we want. The next line:

lockpal = GETCLIP(base||'Lockpal')

creates a variable for holding the status of the Palette, whether you checked the Lock Palette? Gadget or not. It will be 1 if locked, 0 if not. The next few lines hold some important values, the current frame number, main buffer name, swap buffer name, sequence number, and the max (highest) frame.

Pay special attention to the lines starting IF Lockpal then DO. These lines check to see if the palette Lock gadget was checked. If not, the whole IF..THEN..ELSE part is skipped, and the Main buffer is rendered with an unlocked palette. On the other hand, if the gadget was checked, then we go on to see if we're on frame number one. If we are on frame number one, unlock the palette, so we can retrieve it from the first frame when we render it. If we're not on frame number one, then we keep the palette from the first frame by locking the palette. Notice when it says Lockrange 0? You can use 'ranges' with your palette, with is just little segregated chunks. Range 0 means all the colors in the palette, so lockrange 0 means lock all the colors.

This, my friends, is the offending bit of code that was driving me crazy in my perfectly black animation I mentioned last time! Ah ha! We'll have more to say about this in a minute!

After that, the Render Go line sends the main buffer to be rendered.

OK. Now as you remember, at the conclusion of last issue, I wanted a way to pick the palette the animation was going use, rather than have it be generated from the first frame. What we need is a way to select a palette file, and lock it to that before rendering to the anim.

First we need a palette file. This is accomplished by loading a typical frame from your animation, rendering it to the desired number of colors, and then saving the resultant 'RENDER' palette, from the Palette button, select the Render palette (a gadget on the right of the palette Menu, it will have choices like 1-Draw, 2-Draw etc up to Render. And then click the save button. If you're animation has wildly different colors during different parts, make a composite image with a number of different frames, then render it.

Figure 2
Figure 2: Saving the Render Palette

Next, we need to modify the above Render_Amiga.ifx script, but also the render_Amiga.ifx.pre script I alluded to earlier:

/*
 * Render_Amiga.ifx
 * Written by Thomas Krehbiel
 *
 * Render to an Amiga display format.
 *
 * Inputs:
 *    Word(Arg(1),1) = Frame number (1 - N)
 *    Word(Arg(1),2) = Main filename ("-" if not specified)
 *    Word(Arg(1),3) = Swap filename ("-" if not specified)
 *    Word(Arg(1),4) = Sequence number
 *    Word(Arg(1),5) = Total number of frames (N)
 *
 * Returns:
 *    0 if successful, non-zero on failure
 *
 */

OPTIONS RESULTS

base  = 'Autofx_RendAmiga_'

lockpal  = GETCLIP(base||'LockPal')

framenum = Word(Arg(1),1)
mainname = Word(Arg(1),2)
swapname = Word(Arg(1),3)
seqnum   = Word(Arg(1),4)
framemax = Word(Arg(1),5)

/* gracefully exit if no buffer */
GetMain
IF rc ~= 0 THEN EXIT 0

IF lockpal THEN
      LockRange 0 ON
ELSE
   LockRange 0 OFF

Render Go

EXIT

/* End Render_wpal.ifx
   ------------------------------------------------------------
*/

The above modified render_amiga.ifx script, which I have saved as render_wpal.ifx, shows the very simple modification, the IF...THEN...ELSE sequence no longer checks for frame number one, it simply checks to see if the palette gadget was checked or not.

The real fun is in the render_amiga.ifx.pre file. Since that file is so long, and much of it doesn't concern us at this juncture, I'm going to cheat a little, and just show the part I modified, plus enough of the old one so you know where I inserted the modifications.

/* Render_ifx.pre modified by Dave, many lines left out for brevity */

SetRender Amiga
IF rc ~= 0 THEN EXIT rc

Render 'Colors' colorarray.ncolors
Render 'Dither' dithtype dithdir ditherr
Render 'Mode' hname vertarray.vert monarray.monitor

CALL SETCLIP(base||'DithType', dithtype)
CALL SETCLIP(base||'DithDir', dithdir)
CALL SETCLIP(base||'DithErr', ditherr)
CALL SETCLIP(base||'Colors', origcolors)
CALL SETCLIP(base||'Monitor', monitor)
CALL SETCLIP(base||'Horiz', horiz)
CALL SETCLIP(base||'Vert', vert)
CALL SETCLIP(base||'LockPal', lockpal)

/* My Modifications start here */
LockRange 0 OFF

RequestFile '"Enter Filename of Desired Palette:"' 'IMAGEFX3:Storage/Palettes'

IF rc ~= 0 THEN EXIT 0

filename = result

loadpalette filename 8

LockRange 0 On                         

EXIT

/* End Render_wpal.ifx.pre
   ------------------------------------------------------------
*/

Let's see what's happening here. First (after all the normal Render_Amiga.pre stuff happens) I unlock the palette. The next line puts up a file requester, asking for a palette filename. Notice the second part, 'IMAGEFX3:Storage/Palettes', this points the requester right to the directory where my palettes are stored.

What happens is, when you press the 'BEGIN' button in AutoFX, this file requester pops up, you choose your palette file, which then is transferred to the filename.

loadpalette filename 8

This command loads the palette you chose into the palette holder #8, which happens to be the render palette, right where we want it. Finally, the palette is locked again, and this script exits, and the next bit takes over till the whole animation is done.

Phew! Well, that's a lot to chew over for one article, so I'll leave it here for now. Try playing with these scripts, changing them, trying out different things. Be sure not to overwrite your original ImageFX scripts though! Always save your under a new name.

As always, you can reach me via email at: DaveSMatthews@netscape.net

If you have an idea for an article or tutorial please drop an email to the current editor of these tutorial pages.

***


Links: