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
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: 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: 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:
|