mirror of https://github.com/GNOME/gimp.git
936 lines
42 KiB
TeX
936 lines
42 KiB
TeX
\documentclass{article}
|
|
|
|
\setlength{\oddsidemargin}{0in}
|
|
\setlength{\evensidemargin}{0in}
|
|
\setlength{\headsep}{0pt}
|
|
\setlength{\topmargin}{0in}
|
|
\setlength{\textheight}{8.75in}
|
|
\setlength{\textwidth}{6.5in}
|
|
\setlength{\parindent}{0in}
|
|
\setlength{\parskip}{2ex}
|
|
|
|
\usepackage{tabularx}
|
|
\usepackage{multicol}
|
|
\usepackage{epsf}
|
|
\usepackage{amstex}
|
|
\usepackage{array}
|
|
\usepackage{xspace}
|
|
\usepackage{float}
|
|
|
|
\newcommand{\figref}[1]{{\em Figure ~\ref{#1}}\xspace}
|
|
\renewcommand{\labelenumi}{\theenumi.}
|
|
|
|
\floatstyle{ruled}
|
|
\newfloat{code}{h}{loc}
|
|
\floatname{code}{Example Code}
|
|
|
|
\newcommand{\myfigone}[3]{
|
|
\def\@captype{figure}
|
|
\begin{table}
|
|
\bigskip
|
|
\begin{center}
|
|
\leavevmode
|
|
\epsfysize=#2 \epsfbox{#1.eps}
|
|
\caption{#3} \label{#1}
|
|
\end{center}
|
|
\end{table}}
|
|
|
|
\newcommand{\myfigtwo}[3]{
|
|
\def\@captype{figure}
|
|
\begin{table*}
|
|
\bigskip
|
|
\begin{center}
|
|
\leavevmode
|
|
\epsfysize=#2 \epsfbox{#1.eps}
|
|
\caption{#3} \label{#1}
|
|
\end{center}
|
|
\end{table*}}
|
|
|
|
\begin{document}
|
|
|
|
\twocolumn
|
|
|
|
\begin{titlepage}
|
|
\title{{\bf Script-Fu: Graphic Art for Everyone}}
|
|
\author{Spencer Kimball\\
|
|
eXperimental Computing Facility\\
|
|
University of California at Berkeley\\
|
|
spencer@@xcf.berkeley.edu}
|
|
\maketitle
|
|
|
|
\thispagestyle{empty}
|
|
\begin{abstract}
|
|
With the advent of the World Wide Web (WWW), individuals
|
|
have an unprecedented ability to disseminate information at little or
|
|
no cost. Because of its accessibility, the flow of information on the
|
|
WWW is staggering, and appears to be sustaining its incredible rate of
|
|
growth. With so much competing information, presentation becomes
|
|
as--or even more--important than content; visually appealing web pages
|
|
are likely to attract the most attention. {\bf Script-Fu} is a newly
|
|
developed application which automatically creates the graphics
|
|
necessary to present information compellingly. Script-Fu is designed
|
|
to maximize power and flexibility and it accomplishes this goal using
|
|
a three-component architecture. This architecture is composed of an
|
|
image manipulation engine (for the computations necessary to create
|
|
graphics), a scripting language (for precisely describing the
|
|
algorithms required to create the graphics), and a
|
|
facilitator/management program (for user-interface and communication
|
|
between the components). This choice of components maximizes the
|
|
power of Script-Fu, but in some cases lessens the accessibility. For
|
|
example, the image manipulation engine, GIMP, runs only on UNIX
|
|
workstations, not on Macintoshes or PCs. A fourth component, Net-Fu,
|
|
solves this dilemma by providing an alternate interface to Script-Fu,
|
|
making its functionality available to anyone who has access to a WWW
|
|
browser application such as {\it Netscape} or {\it Microsoft Internet
|
|
Explorer}. Using both Script-Fu and the WWW, virtually anyone can
|
|
present information compellingly, and at low cost.
|
|
\end{abstract}
|
|
|
|
\end{titlepage}
|
|
|
|
\section{Introduction}
|
|
|
|
Company logos, product names, and eye-catching slogans are as
|
|
ubiquitous as they are necessary for successful marketing.
|
|
Traditionally, this sort of graphic design work lay squarely in the
|
|
realm of the professional artist. A company which required art for
|
|
magazine ads, CD or record labels, book covers, posters, or product
|
|
brochures would contract the services of a graphic design firm.
|
|
Individuals not associated with large companies had little use for
|
|
such artwork, because both the cost of advertising and the cost of
|
|
graphic design were prohibitive.
|
|
|
|
Things have changed. The cost of advertising has gone through the
|
|
floor, while the cost of graphic design remains high. Individuals now
|
|
have the ability to advertise products, ideas, and opinions, but lack
|
|
the means to present them in a compelling fashion. {\bf Script-Fu}, a
|
|
piece of computer software developed to address this situation, makes
|
|
high-quality graphic design an option available to everyone.
|
|
|
|
The advent of the World Wide Web (WWW) is rapidly changing the face of
|
|
the world's information infrastructure. The WWW is a conglomeration
|
|
of distinct ``web sites'' linked together by what are known as
|
|
``hyperlinks''. It is built on the ``internet'', a global
|
|
communications network for computer-based communications. If the WWW
|
|
were compared to a railway system, web sites would correspond to train
|
|
stations, and hyperlinks to tracks. Web sites contain publicly
|
|
available information including text, images, animations, and sound.
|
|
Users travel from web site to web site to find information of
|
|
interest, using a program known as a ``browser'' ({\it Netscape} and
|
|
{\it Microsoft Internet Expolorer} are examples of widely available
|
|
browsers). The browser, then, is like a train that carries the user
|
|
from one depot of information to the next, following hyperlinks
|
|
between web sites.
|
|
|
|
What makes the WWW so revolutionary is the cost at which it allows
|
|
individuals to disseminate information. Because of the distributed
|
|
architecture of the internet\footnote{The internet was originally
|
|
intended as a network to inter-connect research facilities and
|
|
universities. It was designed so that each participant would have to
|
|
contribute to the overall operation. For example, a computer on the
|
|
internet in Michigan might help forward information from Berkeley to
|
|
MIT.} and the low cost of personal computers, anyone can establish a
|
|
presence on the World Wide Web for under \$10,000. On the WWW,
|
|
individuals have as much right and recourse to advertising as large
|
|
corporations. In this context, ``advertise'' has a wide range of
|
|
meanings--from actual product marketing to information exchange and
|
|
the publication of ideas and opinions.
|
|
|
|
As recently as 1985, the internet consisted of roughly 50 sites.
|
|
Today, the count is higher than 100,000, and is rapidly increasing.
|
|
In fact, the naming conventions which assign each site on the internet
|
|
a unique, identifying name, have to be changed to account for the
|
|
unexpected magnitude of expansion \cite{ipv6}.
|
|
|
|
This expansion of the internet is blamed by most on the staggering
|
|
growth of the world wide web, as universities, companies,
|
|
organizations, and individuals race to take advantage of this nascent
|
|
means of mass-communication. In the confusion of this mad scramble,
|
|
attention spans for web-surfers (users who access the information on
|
|
the WWW) have reached all time lows. Like more traditional forms of
|
|
mass-media--radio and TV, for example--the format and appeal of
|
|
packaging is becoming as important or more important than the actual
|
|
content. Imagine a TV with literally millions of channels available
|
|
and an efficient interface for searching them for items of interest.
|
|
The importance of high quality, eye-catching presentations assumes an
|
|
unprecedented magnitude in this context. It would be a rare
|
|
web-surfer indeed, who would bother with a web page that contained no
|
|
concessions to visual or auditory stimulation.
|
|
|
|
\myfigtwo{timeline}{6cm}{There is an emerging need for graphic art
|
|
solutions that support the needs of individuals, who can't afford
|
|
professional graphic designers.}
|
|
|
|
While the cost of advertising has plummeted with the World Wide Web,
|
|
the cost of graphic design has not decreased. If anything, the
|
|
extreme demand generated by the WWW has pushed the price of graphic
|
|
design through the roof in the short-term; prices will remain high
|
|
until the graphic design industry can grow large enough to satisfy
|
|
current and future demand.
|
|
|
|
The World Wide Web is here to stay. Its growth continues at an almost
|
|
impossible rate and the exploration of its benefits is just beginning.
|
|
The WWW will certainly be here for the next five years, and what the
|
|
future holds is undoubtedly even more surprising than the recent
|
|
advances in information exchange. Through it all, the requirement
|
|
that information be presented compellingly is unlikely to change, as
|
|
human nature seems constant in that regard. Script-Fu targets the
|
|
problem of information packaging and is therefore well-suited to the
|
|
needs of both the present and the immediate future.
|
|
|
|
\section{Requirements}
|
|
|
|
What is ``high-quality graphic art''? This term needs to be defined
|
|
before an application purported to automatically generate graphic art
|
|
is described. Where Script-Fu is concerned, the definition is limited
|
|
to the current standard for {\it logos} typically found on
|
|
professionally designed web pages\footnote {The term should, in fact,
|
|
describe the overall composition of graphics, text and background
|
|
which make up a web page.}. Logos should have the option to be
|
|
generated from a wide range of typefaces, sizes, colors, backgrounds,
|
|
and styles, including such exotic motifs as neon, chrome, crystal, and
|
|
carved marble or wood. The task that Script-Fu tackles is simply put:
|
|
to generate logos in a wide variety of styles with configurable
|
|
options, at a level of quality comparable to professionally done
|
|
graphic design work. Additionally, the graphic art should be
|
|
generated automatically, and in tens of seconds, where traditional
|
|
artists painstakingly produce artwork on a timescale of hours.
|
|
\figref{logo} is a \emph{very} simple example of a logo which
|
|
Script-Fu might generate\footnote {We will discuss the creation of
|
|
this logo in detail throughout the following sections. For an actual
|
|
Script-Fu {\it scheme} script that generates similar logos, refer to
|
|
Appendix A. {\bf Warning:} Unless you are familiar with both
|
|
programming languages and typical {\it Photoshop}\cite{photoshop}/{\it
|
|
GIMP}\cite{GIMP} usage, the code listed in the appendix will be
|
|
confusing.}.
|
|
|
|
Many factors must be considered in the design of an application which
|
|
meets the requirements discussed above. Most important are
|
|
flexibility and power. To meet the requirement that it generate
|
|
``high-quality'' graphic art, Script-Fu must be flexible and easy to
|
|
expand upon; new and more impressive logo designs are constantly
|
|
evolving and must be incorporated into the system as they emerge.
|
|
Script-Fu must also be extremely powerful, as impressive logos
|
|
typically involve a complex process which--in the case of automated
|
|
logo creation--requires that software make decisions that were
|
|
formerly made by human artists. Sections 3 and 4 in this paper
|
|
discuss the architecture necessary to achieve these goals, as well as
|
|
how the components of the architecture interact to get the job done.
|
|
|
|
One factor which is easily overlooked, but of utmost importance, is
|
|
the user-interface. Script-Fu has a traditional user interface in the
|
|
sense that when you run the software on a computer, it displays a
|
|
window with the necessary options for logo generation. However, to
|
|
maximize the availability and appeal of Script-Fu, a secondary
|
|
interface called {\bf Net-Fu} was designed. Section 5 discusses this
|
|
additional interface in detail.
|
|
|
|
\myfigone{logo}{6cm}{A simple example of a composited logo. The logo
|
|
consists of highlights, the logo text, and shadows.}
|
|
|
|
\section{Architecture}
|
|
|
|
The architecture of Script-Fu is carefully designed with the goals of
|
|
flexibility and power in mind. The architecture consists of three
|
|
primary components and is illustrated in \figref{architecture}:
|
|
\begin{itemize}
|
|
\item An underlying image manipulation engine for computing each step
|
|
of the logo generation process.
|
|
\item A mechanism for automating the logo creation process.
|
|
\item An intermediary which oversees the progress of the other two
|
|
components and facilities communication between them.
|
|
\end{itemize}
|
|
|
|
\subsection{GIMP--Image Manipulation Engine}
|
|
|
|
In theory, Script-Fu could include all of the necessary image
|
|
manipulation operations for creating logos. However, this would
|
|
involve hundreds of thousands of lines of program code and immense
|
|
amounts of development time. Instead, the architecture calls for the
|
|
leveraging of an existing image manipulation ``engine''--in the
|
|
context of our simple logo example (\figref{logo}), this is a piece of
|
|
software that actually performs the computations necessary to create
|
|
highlights, text, and shadows and then combine them into a final logo.
|
|
|
|
\myfigone{architecture}{6cm}{Script-Fu and GIMP are stand-alone
|
|
executables running on one machine, communicating with each other.}
|
|
|
|
Professional graphic design artists have long used Photoshop
|
|
\cite{photoshop}, a software package from Adobe for their image
|
|
manipulation needs. Photoshop is a complicated, powerful, and
|
|
highly-respected piece of software that is employed in nearly all
|
|
computer-based image manipulation tasks (such as photo-retouching,
|
|
graphic art design, and image composition). Photoshop was not chosen
|
|
for use with Script-Fu. There are a number of reasons for this
|
|
decision. Among them are the price point of Photoshop--around \$500,
|
|
the lack of support for UNIX platforms--which are better suited to
|
|
batch processing, and most importantly, the lack of a facility for
|
|
supporting complex, automated control. In plain English, Photoshop
|
|
does not have the necessary means through which other applications can
|
|
direct its actions.
|
|
|
|
Instead, Script-Fu was implemented using an image manipulation engine
|
|
known as the GNU Image Manipulation Program (GIMP) \cite{GIMP}. GIMP
|
|
is free software (meaning both its source code, and the runnable
|
|
application can be downloaded and used free of
|
|
charge)\footnote{ftp://ftp.xcf.berkeley.edu/pub/gimp}, making it
|
|
possible to offer Script-Fu without a restrictive usage policy or the
|
|
requirement of commercial software. GIMP runs on nearly all UNIX
|
|
platforms, the ideal setting for large batch processing operations.
|
|
Finally, GIMP has a facility for supporting extensions, which are
|
|
perfectly suited to the needs of Script-Fu. A GIMP extension is a
|
|
stand-alone program that extends the functionality of the main
|
|
application. The extension and GIMP communicate with each other, and
|
|
through this line of communication, the extension can command GIMP to
|
|
execute any operation\footnote{See appendix B for a discussion of
|
|
extensions and how they interact with GIMP}.
|
|
|
|
\subsection{Scheme--Scripting Language}
|
|
|
|
There are two primary mechanisms typically employed for automated
|
|
processing of the type used in Script-Fu: batch processing and
|
|
scripting. Batch processing is used primarily for automating only the
|
|
most simplistic procedures--tasks in which nothing changes from one
|
|
invocation to the next, and no decisions need to be made based on
|
|
variable input values. This is not a suitable solution for Script-Fu.
|
|
Based on the name {\bf Script}-Fu, it should be obvious that scripting
|
|
is the solution of choice.
|
|
|
|
Scripting allows far more flexibility than batch processing because it
|
|
often incorporates an actual programming language. A programming
|
|
language is a means to specify an algorithm (a list of steps for the
|
|
computer to complete) with complex, language-like control structures.
|
|
For example, decisions can be made by evaluating whether a given
|
|
condition is true and executing one command if it is, and another
|
|
command if it is not. Here is a good example of such a control
|
|
structure, commonly referred to as an {\it if-then-else} structure:
|
|
|
|
{\scriptsize
|
|
\begin{verbatim}
|
|
if (image_is_color (img)) then
|
|
set_color (RED)
|
|
else
|
|
set_color (BLACK)
|
|
\end{verbatim}}
|
|
|
|
The {\it if-then-else} structure demonstrated in the example above
|
|
evaluates whether the image contained in the {\it img} variable is a
|
|
color image. {\it If} it is, then the color is set to red; otherwise,
|
|
the color is set to black. This simple example would be extended in an
|
|
actual script to make complex decisions based on the user's specified
|
|
logo preferences.
|
|
|
|
This short {\it if-then-else} example also includes what is known in
|
|
programming languages as a ``variable''. A variable in programming is
|
|
quite similar to a variable in algebra. It is simply a symbol that
|
|
represents a value. Variables are used both in algebra and in
|
|
programming because it is more convenient (and more powerful) to
|
|
substitute variables for actual values in an expression.
|
|
|
|
Loops are another example of control that is available when a
|
|
programming language is used to specify the steps the computer must
|
|
take to complete an algorithm. Loops allow a given operation to be
|
|
repeated. In batch processing, this simply isn't possible without
|
|
explicitly requesting the operation as many times as you'd like it
|
|
done. Here is a comparison of the commands necessary in both batch
|
|
processing and scripting to draw five circles:
|
|
|
|
\begin{itemize}
|
|
\item Batch Processing\\
|
|
{\scriptsize
|
|
\begin{verbatim}
|
|
draw_circle (100, 50, 50)
|
|
draw_circle (200, 50, 50)
|
|
draw_circle (300, 50, 50)
|
|
draw_circle (400, 50, 50)
|
|
draw_circle (500, 50, 50)
|
|
\end{verbatim}}
|
|
\item Scripting\\
|
|
{\scriptsize
|
|
\begin{verbatim}
|
|
for (i = 1 to 5)
|
|
draw_circle (i * 100, 50, 50)
|
|
\end{verbatim}}
|
|
\end{itemize}
|
|
|
|
Script-Fu uses a programming language known as {\bf
|
|
Scheme}\footnote{Script-Fu actually uses SIOD, a small implementation
|
|
of Scheme \cite{siod}} \cite{scheme} to implement its scripting.
|
|
Scheme is a compact, but fully-featured programming language. It
|
|
affords the programmer the flexibility necessary for automatic logo
|
|
generation, without burdening him with unnecessary complexity. Logo
|
|
scripts are written in Scheme and a program called an interpreter
|
|
reads through them, evaluating each expression as it goes. This
|
|
scheme interpreter is not actually a separate program in the Script-Fu
|
|
architecture. Instead, it is part of the Script-Fu program, which
|
|
simplifies the overall architecture. The scheme interpreter is quite
|
|
small, and therefore does not add significant clutter to Script-Fu.
|
|
|
|
\subsection{Script-Fu--Management}
|
|
|
|
The final component is the Script-Fu program itself. Script-Fu is
|
|
implemented as a GIMP extension. In essence, it acts as manager and
|
|
facilitator between the scheme interpreter and GIMP. It establishes
|
|
the lines of communication and forwards messages between them. It
|
|
also presents the user with an interface for selecting which script to
|
|
run, and which parameters to run the script with. Parameters for
|
|
running a script typically include things like the typeface, the size,
|
|
the text string, and colors. After the user has selected a script and
|
|
entered the input parameters, Script-Fu formulates a command and sends
|
|
it to the scheme interpreter, which in turn begins to process the
|
|
script.
|
|
|
|
\section{Component Interaction}
|
|
|
|
The three components that comprise Script-Fu work together to generate
|
|
a logo. Their interaction is fairly straightforward and consists of
|
|
six steps:
|
|
|
|
\begin{enumerate}
|
|
\item Script-Fu presents the user with an interface allowing a
|
|
style of logo to be selected and input parameters associated with that
|
|
style to be set.
|
|
\item Once a logo is selected, Script-Fu formulates a command based on
|
|
the user inputs and sends it to the Scheme interpreter. The
|
|
interpreter begins to process the selected script.
|
|
\item The Scheme interpreter reads a command from the script,
|
|
and if it is GIMP-related, forwards it to Script-Fu. Otherwise goto
|
|
step 6.
|
|
\item If the interpreter forwarded a command, Script-Fu parses it and
|
|
reformats it so that GIMP will accept it. Script-Fu then requests
|
|
that GIMP execute the command and waits for GIMP to signal success or
|
|
failure.
|
|
\item GIMP executes the command incoming from Script-Fu, and on
|
|
success, returns any values which the command requires as outputs. On
|
|
failure, GIMP returns an error message.
|
|
\item The Scheme interpreter checks if the script has been fully
|
|
processed. If so, then the logo is finished; otherwise, goto step 3.
|
|
\end{enumerate}
|
|
|
|
\section{Net-Fu}
|
|
|
|
Script-Fu and GIMP run on UNIX workstations, which severely limit the
|
|
breadth of the user base. The users who would most benefit from the
|
|
advent of an automated graphic design utility are primarily PC users
|
|
running either Apple's MacOS or Microsoft's Windows NT and Windows 95.
|
|
Therefore, a fourth and final component is necessary to complete
|
|
Script-Fu.
|
|
|
|
\myfigone{net-fu}{6cm}{Net-Fu adds one additional component to the
|
|
Script-fu/GIMP architecture: A WWW user interface written as a {\it
|
|
Java} applet, and capable of running on any {\it Java}-equipped web browser.}
|
|
|
|
This additional component is called {\bf Net-Fu}, and serves to bridge
|
|
the gap between the UNIX-based Script-Fu and the masses. Instead of
|
|
porting Script-Fu to MacOS or Windows 95, Net-Fu solves the problem of
|
|
usability by providing an additional interface to Script-Fu's
|
|
functionality. Net-Fu is implemented as a Java applet--programs which
|
|
can be downloaded on the World Wide Web and run on any kind of
|
|
computer, from UNIX machines to Macintoshes to PCs. Java applets can
|
|
be run from within web browsers, which means that anyone with access
|
|
to the WWW (which is just about everyone these days), can use Net-Fu.
|
|
|
|
Net-Fu provides an interface similar to the one which Script-Fu
|
|
normally provides on the local UNIX machine\footnote{Refer to appendix
|
|
D for images of the Net-Fu user interface}: it allows a style of
|
|
script to be selected and then prompts the user for logo parameters
|
|
such as typeface, size, and the text string. While Script-Fu simply
|
|
takes the user input and feeds it directly to the Scheme interpreter,
|
|
Net-Fu must transmit its request to Script-Fu, which then feeds it to
|
|
the Scheme interpreter.
|
|
|
|
When Script-Fu is run, it can be instructed not to display an
|
|
interface, but instead to act as a server to which any other program
|
|
can send commands which will be processed as if they were entered by
|
|
Script-Fu's normal user-interface. If Net-Fu is the intended
|
|
interface, Script-Fu will be instructed to enter server-mode and will
|
|
then simply await commands from programs such as Net-Fu. To clarify,
|
|
here is a typical sequence of events that occur using Net-Fu:
|
|
|
|
\begin{enumerate}
|
|
\item A user in Sweden wants to create a title logo that appears to be
|
|
made from green, neon tubing and reads ``Jens' Cocktails''. The user
|
|
directs his web browser to the Net-Fu address: {\it
|
|
http://scheme.xcf.berkeley.edu/net-fu/}.
|
|
\item Jens' browser will now display a table containing the various
|
|
styles of logos available for creation through Net-Fu. Each logo style
|
|
entry in the table contains a short description of the style and a
|
|
preview.
|
|
\item Jens selects the ``Neon'' style and is subsequently presented
|
|
with a user interface which prompts him for the following inputs:
|
|
\begin{itemize}
|
|
\item {\it Text}--He enters ``Jens' Cocktails''
|
|
\item {\it Text Size}--He keeps the default value of 100 pixels
|
|
\item {\it Typeface}--He keeps the default, ``Blippo'', a font with
|
|
evenly rounded characters--quite appropriate for neon.
|
|
\item {\it Tube Color}--He selects a bright green with a hint of yellow.
|
|
\end{itemize}
|
|
\item Jens then clicks the ``Run'' button in the Net-Fu interface and
|
|
waits patiently for his logo.
|
|
\item As soon as the ``Run'' button is clicked, Net-Fu gathers all of
|
|
the information entered by Jens and opens a connection to the
|
|
Script-Fu server running on a machine in Berkeley, CA. Net-Fu then
|
|
forwards Jens' command to Script-Fu and waits until Script-Fu returns.
|
|
\item Script-Fu receives Jens' command and enters active
|
|
processing mode, where it no longer listens for commands, but instead
|
|
begins to process the Neon script to Jens' specifications. When it has
|
|
finished the logo, Script-Fu returns the location.
|
|
\item Net-Fu receives the location of the logo from Script-Fu
|
|
and directs Jens' browser there.
|
|
\item Jens claps his hands in glee, as he has created the logo of his
|
|
dreams in seconds, without an ounce of effort, and certainly without
|
|
straining his limited artistic talents.
|
|
\end{enumerate}
|
|
|
|
\section{Conclusions}
|
|
|
|
With the advent of the World Wide Web (WWW), mass communication is
|
|
available to the average individual at a fraction of its historical
|
|
price. This unprecedented development makes it possible for anyone to
|
|
advertise products, exchange information, and communicate ideas.
|
|
However, the massive volume of information which flows through the WWW
|
|
is a mixed blessing: while it does allow anyone to contribute, it also
|
|
reduces the liklihood that a particular piece of information will be
|
|
absorbed by a significant number of people. Like other more
|
|
traditional means of mass media--such as TV and radio--the content on
|
|
the WWW must be accompanied by attractive packaging to have a large
|
|
impact.
|
|
|
|
Script-Fu delivers this attractive packaging at no cost, in mere
|
|
seconds, and without requiring artistic talent. Script-Fu is capable
|
|
of delivering artwork which rivals the quality of that done by
|
|
professional graphic designers. Using Script-Fu and the WWW,
|
|
virtually anyone can advertise compellingly, and at almost no cost.
|
|
|
|
Script-Fu consists of three primary components. The first is GIMP, an
|
|
image manipulation engine which does the actual computations necessary
|
|
in creating a logo. The second is the scripting language (Scheme),
|
|
which specifies the algorithms which define the process that leads to
|
|
a logo. The third and final component is a GIMP extension called
|
|
Script-Fu, which manages the entire process of creating a logo--from
|
|
communication between the Scheme interpreter and GIMP, to a user
|
|
interface.
|
|
|
|
Net-Fu is an optional fourth component and provides an additional user
|
|
interface which is accessible to nearly everyone. It is implemented
|
|
as a Java applet and can be accessed through the World Wide Web.
|
|
Net-Fu allows anyone with a web browser to access the power of
|
|
Script-Fu.
|
|
|
|
\section{Acknowledgements}
|
|
Special thanks to Yaroslav Faybishenko for his speedy implementation
|
|
of the Net-Fu Java applet. Beyond this inadequate mention, Peter
|
|
Mattis should be recognized for his work on GIMP. The software has
|
|
come a long way in two years.
|
|
|
|
\begin{flushleft}
|
|
\begin{thebibliography}{References}
|
|
\bibitem{photoshop} Adobe Systems, Inc. Photoshop (tm) 3.0,
|
|
Computer Program, 1994.
|
|
\bibitem{foley} J. D. Foley, A. Dam, S. K. Feiner, J. F. Hughes,
|
|
\emph{Computer Graphics: Principles and Practice},
|
|
Addison-Wesley, NY, 1992.
|
|
\bibitem{GIMP} S. Kimball, P. Mattis, GNU Image Manipulation
|
|
Program (GIMP), Computer Program, 1996-1997.
|
|
\bibitem{hearn} D. Hearn, M. P. Baker,
|
|
\emph{Computer Graphics},
|
|
Prentice Hall, NJ, 1994.
|
|
\bibitem{ipv6} R. M. Hinden, ``IP Next Generation Overview'',
|
|
\emph{Communications of the ACM},
|
|
June 1996/Vol 39, No. 6.
|
|
\bibitem{scheme} H. Abelson, G. J. Sussman,
|
|
\emph{Structure and Interpretation of Computer Programs},
|
|
The MIT Press, MA, 1985.
|
|
\bibitem{siod} G. J. Carrette, Scheme In One Defun (SIOD),
|
|
Computer Program, 1996.
|
|
\end{thebibliography}
|
|
\end{flushleft}
|
|
|
|
\onecolumn
|
|
\appendix
|
|
|
|
\section{Example Scripts}
|
|
|
|
\subsection{Simple Script for HDS Logos}
|
|
{\scriptsize
|
|
\begin{verbatim}
|
|
; HIGHLIGHT-DROP-SHADOW-LOGO
|
|
; draw the specified text over a background with a drop shadow and a highlight
|
|
|
|
(define (color-highlight color)
|
|
(let ((r (car color))
|
|
(g (cadr color))
|
|
(b (caddr color)))
|
|
(set! r (+ r (* (- 255 r) 0.75)))
|
|
(set! g (+ g (* (- 255 g) 0.75)))
|
|
(set! b (+ b (* (- 255 b) 0.75)))
|
|
(list r g b)))
|
|
|
|
(define (hds-logo text size font bg-color text-color)
|
|
(let* ((img (car (gimp-image-new 256 256 RGB)))
|
|
(text-layer (car (gimp-text img -1 0 0 text 10 TRUE size PIXELS "*" font "*" "*" "*" "*")))
|
|
(width (car (gimp-drawable-width text-layer)))
|
|
(height (car (gimp-drawable-height text-layer)))
|
|
(bg-layer (car (gimp-layer-new img width height RGB_IMAGE "Background" 100 NORMAL)))
|
|
(highlight-layer (car (gimp-layer-copy text-layer TRUE)))
|
|
(shadow-layer (car (gimp-layer-new img width height RGBA_IMAGE "Shadow" 100 MULTIPLY)))
|
|
(old-fg (car (gimp-palette-get-foreground)))
|
|
(old-bg (car (gimp-palette-get-background))))
|
|
(gimp-image-undo-disable img)
|
|
(gimp-image-resize img width height 0 0)
|
|
(gimp-image-add-layer img bg-layer 1)
|
|
(gimp-image-add-layer img shadow-layer 1)
|
|
(gimp-image-add-layer img highlight-layer 1)
|
|
(gimp-palette-set-background text-color)
|
|
(gimp-layer-set-preserve-trans text-layer TRUE)
|
|
(gimp-edit-fill img text-layer)
|
|
(gimp-edit-clear img shadow-layer)
|
|
(gimp-palette-set-background (color-highlight text-color))
|
|
(gimp-layer-set-preserve-trans highlight-layer TRUE)
|
|
(gimp-edit-fill img highlight-layer)
|
|
(gimp-palette-set-background bg-color)
|
|
(gimp-drawable-fill bg-layer BG-IMAGE-FILL)
|
|
(gimp-selection-layer-alpha img text-layer)
|
|
(gimp-palette-set-background '(0 0 0))
|
|
(gimp-selection-feather img 7.5)
|
|
(gimp-edit-fill img shadow-layer)
|
|
(gimp-selection-none img)
|
|
(gimp-palette-set-foreground '(255 255 255))
|
|
(gimp-blend img text-layer FG-BG-RGB MULTIPLY RADIAL 100 20 FALSE 0 0 width height)
|
|
(gimp-layer-translate shadow-layer 3 3)
|
|
(gimp-layer-translate highlight-layer -2 -2)
|
|
(gimp-layer-set-name text-layer text)
|
|
(gimp-layer-set-name highlight-layer "Highlight")
|
|
(gimp-palette-set-background old-bg)
|
|
(gimp-palette-set-foreground old-fg)
|
|
(gimp-image-undo-enable img)
|
|
(gimp-display-new img)))
|
|
\end{verbatim}}
|
|
|
|
\subsection{Complex Script for Crystal Logos}
|
|
|
|
{\scriptsize
|
|
\begin{verbatim}
|
|
; CRYSTAL
|
|
; Create a text effect that simulates crystal
|
|
|
|
(define (set-pt a index x y)
|
|
(prog1
|
|
(aset a (* index 2) x)
|
|
(aset a (+ (* index 2) 1) y)))
|
|
|
|
(define (spline1)
|
|
(let* ((a (cons-array 18 'byte)))
|
|
(set-pt a 0 0 0)
|
|
(set-pt a 1 31 235)
|
|
(set-pt a 2 63 23)
|
|
(set-pt a 3 95 230)
|
|
(set-pt a 4 127 25)
|
|
(set-pt a 5 159 210)
|
|
(set-pt a 6 191 20)
|
|
(set-pt a 7 223 240)
|
|
(set-pt a 8 255 31)
|
|
a))
|
|
|
|
(define (crystal-brush brush-size)
|
|
(cond ((<= brush-size 5) "Circle (05)")
|
|
((<= brush-size 7) "Circle (07)")
|
|
((<= brush-size 9) "Circle (09)")
|
|
((<= brush-size 11) "Circle (11)")
|
|
((<= brush-size 13) "Circle (13)")
|
|
((<= brush-size 15) "Circle (15)")
|
|
((<= brush-size 17) "Circle (17)")
|
|
(else "Circle Fuzzy (19)")))
|
|
|
|
(define (shadows val)
|
|
(/ (* 0.96 val) 2.55))
|
|
|
|
(define (midtones val)
|
|
(/ val 2.55))
|
|
|
|
(define (highlights val)
|
|
(/ (* 1.108 val) 2.55))
|
|
|
|
(define (rval col)
|
|
(car col))
|
|
|
|
(define (gval col)
|
|
(cadr col))
|
|
|
|
(define (bval col)
|
|
(caddr col))
|
|
|
|
(define (sota-scale val scale chrome-factor)
|
|
(* (sqrt val) (* scale chrome-factor)))
|
|
|
|
(define (crystal-logo chrome-factor text size font bg-img env-map)
|
|
(let* ((img (car (gimp-image-new 256 256 GRAY)))
|
|
(back-img (car (gimp-file-load 1 bg-img bg-img)))
|
|
(back-layer (car (gimp-image-active-drawable back-img)))
|
|
(banding-img (car (gimp-file-load 1 env-map env-map)))
|
|
(banding-layer (car (gimp-image-active-drawable banding-img)))
|
|
(b-size (sota-scale size 2 chrome-factor))
|
|
(offx1 (sota-scale size 0.33 chrome-factor))
|
|
(offy1 (sota-scale size 0.25 chrome-factor))
|
|
(offx2 (sota-scale size (- 0.33) chrome-factor))
|
|
(offy2 (sota-scale size (- 0.25) chrome-factor))
|
|
(feather (sota-scale size 0.5 chrome-factor))
|
|
(blur (sota-scale size 0.5 chrome-factor))
|
|
(displace (sota-scale size 0.25 chrome-factor))
|
|
(brush-size (sota-scale size 0.5 chrome-factor))
|
|
(text-layer (car (gimp-text img -1 0 0 text b-size TRUE size PIXELS "*" font "*" "*" "*" "*")))
|
|
(width (car (gimp-drawable-width text-layer)))
|
|
(height (car (gimp-drawable-height text-layer)))
|
|
(tile-ret (plug-in-tile 1 back-img back-layer width height))
|
|
(tile-img (car tile-ret))
|
|
(tile-layer (cadr tile-ret))
|
|
(bg-layer (car (gimp-layer-copy tile-layer TRUE)))
|
|
(layer1 (car (gimp-layer-copy banding-layer TRUE)))
|
|
(layer2 (car (gimp-layer-new img width height GRAYA_IMAGE "Layer 2" 100 DIFFERENCE)))
|
|
(layer3 (car (gimp-layer-new img width height GRAYA_IMAGE "Layer 3" 100 NORMAL)))
|
|
(layer-mask 0)
|
|
(layer-mask2 0)
|
|
(disp-map 0)
|
|
(old-fg (car (gimp-palette-get-foreground)))
|
|
(old-bg (car (gimp-palette-get-background)))
|
|
(old-brush (car (gimp-brushes-get-brush))))
|
|
(gimp-image-delete banding-img)
|
|
(gimp-image-delete back-img)
|
|
(gimp-image-delete tile-img)
|
|
(gimp-image-undo-disable img)
|
|
(gimp-image-resize img width height 0 0)
|
|
(gimp-image-add-layer img layer3 0)
|
|
(gimp-image-add-layer img layer2 0)
|
|
(gimp-palette-set-background '(255 255 255))
|
|
(gimp-selection-none img)
|
|
(gimp-edit-fill img layer2)
|
|
(gimp-edit-fill img layer3)
|
|
(gimp-layer-set-visible text-layer FALSE)
|
|
|
|
(gimp-selection-layer-alpha img text-layer)
|
|
(gimp-palette-set-background '(0 0 0))
|
|
(gimp-selection-translate img offx1 offy1)
|
|
(gimp-selection-feather img feather)
|
|
(gimp-edit-fill img layer2)
|
|
(gimp-selection-translate img (* 2 offx2) (* 2 offy2))
|
|
(gimp-edit-fill img layer3)
|
|
(gimp-selection-none img)
|
|
(set! layer2 (car (gimp-image-merge-visible-layers img CLIP-TO-IMAGE)))
|
|
(gimp-invert img layer2)
|
|
|
|
(gimp-image-add-layer img layer1 0)
|
|
(gimp-layer-scale layer1 width height FALSE)
|
|
(plug-in-gauss-iir 1 img layer1 10 TRUE TRUE)
|
|
(gimp-layer-set-opacity layer1 50)
|
|
(set! layer1 (car (gimp-image-merge-visible-layers img CLIP-TO-IMAGE)))
|
|
(gimp-curves-spline img layer1 0 18 (spline1))
|
|
|
|
(set! layer-mask (car (gimp-layer-create-mask layer1 BLACK-MASK)))
|
|
(gimp-image-add-layer-mask img layer1 layer-mask)
|
|
(gimp-selection-layer-alpha img text-layer)
|
|
(gimp-palette-set-background '(255 255 255))
|
|
(gimp-edit-fill img layer-mask)
|
|
|
|
(set! disp-map (car (gimp-selection-save img)))
|
|
(gimp-brushes-set-brush (crystal-brush brush-size))
|
|
(gimp-palette-set-foreground '(0 0 0))
|
|
(gimp-edit-stroke img disp-map)
|
|
(gimp-selection-none img)
|
|
|
|
(plug-in-gauss-rle 1 img disp-map blur TRUE TRUE)
|
|
(gimp-levels img disp-map 0 0 255 1.0 96 255)
|
|
|
|
(if (= (car (gimp-drawable-is-rgb bg-layer)) 1)
|
|
(gimp-convert-rgb img))
|
|
|
|
(gimp-image-add-layer img bg-layer 2)
|
|
(set! layer2 (car (gimp-layer-copy bg-layer TRUE)))
|
|
(gimp-image-add-layer img layer2 1)
|
|
|
|
(plug-in-displace 1 img layer2 displace displace TRUE TRUE disp-map disp-map 0)
|
|
(set! layer-mask2 (car (gimp-layer-create-mask layer2 BLACK-MASK)))
|
|
(gimp-image-add-layer-mask img layer2 layer-mask2)
|
|
(gimp-selection-layer-alpha img text-layer)
|
|
(gimp-palette-set-background '(255 255 255))
|
|
(gimp-edit-fill img layer-mask2)
|
|
|
|
(gimp-selection-none img)
|
|
(gimp-levels img layer2 0 0 200 1.5 50 255)
|
|
(gimp-layer-set-mode layer1 OVERLAY)
|
|
|
|
(plug-in-gauss-rle 1 img text-layer blur TRUE TRUE)
|
|
(gimp-layer-set-preserve-trans text-layer TRUE)
|
|
(gimp-palette-set-background '(0 0 0))
|
|
(gimp-edit-fill img text-layer)
|
|
(gimp-layer-set-mode text-layer OVERLAY)
|
|
(gimp-layer-translate text-layer offx1 offy1)
|
|
|
|
(gimp-image-remove-channel img disp-map)
|
|
|
|
(gimp-layer-set-visible text-layer TRUE)
|
|
(gimp-layer-set-name layer1 "Crystal")
|
|
(gimp-layer-set-name layer2 "Interior")
|
|
(gimp-layer-set-name bg-layer "Background")
|
|
(gimp-layer-set-name text-layer "Shadow")
|
|
|
|
(gimp-palette-set-foreground old-fg)
|
|
(gimp-palette-set-background old-bg)
|
|
(gimp-brushes-set-brush old-brush)
|
|
(gimp-image-undo-enable img)
|
|
(gimp-display-new img)))
|
|
\end{verbatim}}
|
|
\twocolumn
|
|
|
|
\section{GIMP Extensions}
|
|
|
|
A computer application is generally a stand-alone program, whose
|
|
source code contains everything necessary for full functionality. In
|
|
this common case, adding additional features to the application
|
|
requires that the original source code be modified, recompiled, and
|
|
finally redistributed to its users. This process of introducing new
|
|
features is highly prone to programmer error, often resulting in a
|
|
host of new problems, sometimes even with pre-existing features. A
|
|
superior method for extending the functionality of an application is
|
|
through extension modules: independent applications which implement
|
|
additional features and then make them available to the main
|
|
application.
|
|
|
|
The GIMP and its extensions communicate by invoking commands from a
|
|
database of procedures. Procedures are pieces of functionality
|
|
provided by GIMP, its plug-ins, and its extensions. Procedures take
|
|
as input a list of arguments, execute based on the values of those
|
|
arguments, and finally return a list of values. There are procedures
|
|
for every piece of internal functionality in the GIMP as well as for
|
|
every plug-in written to date. In total, there are over 275
|
|
procedures stored in GIMP's ``procedural database''. The following are
|
|
examples of procedures called by the simple script from Appendix A:
|
|
|
|
\begin{itemize}
|
|
\item {\scriptsize{\bf gimp\_image\_new} {\it width, height, type}\\
|
|
Creates a new image, undisplayed with the specified extents and type.
|
|
A layer should be created and added before this image is displayed, or
|
|
subsequent calls to 'gimp\_display\_new' with this image as an argument
|
|
will fail. Layers can be created using the 'gimp\_layer\_new' commands.
|
|
They can be added to an image using the 'gimp\_image\_add\_layer'
|
|
command.\\
|
|
\bf Inputs \rm
|
|
\begin{itemize}
|
|
\item {\it width} (PDB\_INT32)--The width of the image
|
|
\item {\it height} (PDB\_INT32)--The height of the image
|
|
\item {\it type} (PDB\_INT32)--The type of image: \{ RGB (0), GRAY (1), INDEXED (2) \}
|
|
\end{itemize}
|
|
\bf Outputs \rm
|
|
\begin{itemize}
|
|
\item {\it image} (PDB\_IMAGE)--The ID of the newly created image
|
|
\end{itemize}}
|
|
|
|
\item {\scriptsize{\bf gimp\_text} {\it image, drawable, x, y, text, border, antialias, size, size\_type, foundry, family, weight, slant, set\_width, spacing}\\
|
|
This tool requires font information in the form of seven parameters:
|
|
\{size, foundry, family, weight, slant, set\_width, spacing\}. The
|
|
font size can either be specified in units of pixels or points, and
|
|
the appropriate metric is specified using the size\_type argument. The
|
|
x and y parameters together control the placement of the new text by
|
|
specifying the upper left corner of the text bounding box. If the
|
|
antialias parameter is non-zero, the generated text will blend more
|
|
smoothly with underlying layers. This option requires more time and
|
|
memory to compute than non-antialiased text; the resulting floating
|
|
selection or layer, however, will require the same amount of memory
|
|
with or without antialiasing. If the specified drawable parameter is
|
|
valid, the text will be created as a floating selection attached to
|
|
the drawable. If the drawable parameter is not valid (-1), the text
|
|
will appear as a new layer. Finally, a border can be specified around
|
|
the final rendered text. The border is measured in pixels.\\
|
|
\bf Inputs \rm
|
|
\begin{itemize}
|
|
\item {\it image} (PDB\_IMAGE)--The image
|
|
\item {\it drawable} (PDB\_DRAWABLE)--The affected drawable: (-1 for a new text layer)
|
|
\item {\it x} (PDB\_FLOAT)--The x coordinate for the left side of text bounding box
|
|
\item {\it y} (PDB\_FLOAT)--The y coordinate for the top of text bounding box
|
|
\item {\it text} (PDB\_STRING)--The text to generate
|
|
\item {\it border} (PDB\_INT32)--The size of the border: border >= 0
|
|
\item {\it antialias} (PDB\_INT32)--Generate antialiased text
|
|
\item {\it size} (PDB\_FLOAT)--The size of text in either pixels or points
|
|
\item {\it size\_type} (PDB\_INT32)--The units of the specified size: \{ PIXELS (0), POINTS (1) \}
|
|
\item {\it foundry} (PDB\_STRING)--The font foundry, "*" for any
|
|
\item {\it family} (PDB\_STRING)--The font family, "*" for any
|
|
\item {\it weight} (PDB\_STRING)--The font weight, "*" for any
|
|
\item {\it slant} (PDB\_STRING)--The font slant, "*" for any
|
|
\item {\it set\_width} (PDB\_STRING)--The font set-width parameter, "*" for any
|
|
\item {\it spacing} (PDB\_STRING)--The font spacing, "*" for any
|
|
\end{itemize}
|
|
\bf Outputs \rm
|
|
\begin{itemize}
|
|
\item {\it text\_layer} (PDB\_LAYER)--The new text layer
|
|
\end{itemize}}
|
|
|
|
\item {\scriptsize{\bf gimp\_blend} {\it image, drawable, blend\_mode, paint\_mode, gradient\_type, opacity, offset, repeat, x1, y1, x2, y2}\\
|
|
This tool requires information on the paint application mode, the
|
|
blend mode, and the gradient type. It creates the specified variety
|
|
of blend using the starting and ending coordinates as defined for each
|
|
gradient type.\\
|
|
\bf Inputs \rm
|
|
\begin{itemize}
|
|
\item {\it image} (PDB\_IMAGE)--The image
|
|
\item {\it drawable} (PDB\_DRAWABLE)--The affected drawable
|
|
\item {\it blend\_mode} (PDB\_INT32)--The type of blend: \{ FG-BG-RGB (0), FG-BG-HSV (1), FG-TRANS (2), CUSTOM (3) \}
|
|
\item {\it paint\_mode} (PDB\_INT32)--The paint application mode: \{ NORMAL (0), DISSOLVE (1), BEHIND (2), MULTIPLY (3), SCREEN (4), OVERLAY (5) DIFFERENCE (6), ADDITION (7), SUBTRACT (8), DARKEN-ONLY (9), LIGHTEN-ONLY (10), HUE (11), SATURATION (12), COLOR (13), VALUE (14) \}
|
|
\item {\it gradient\_type} (PDB\_INT32)--The type of gradient: \{ LINEAR (0), BILINEAR (1), RADIAL (2), SQUARE (3), CONICAL-SYMMETRIC (4), CONICAL-ASYMMETRIC (5), SHAPEBURST-ANGULAR (6), SHAPEBURST-SPHERICAL (7), SHAPEBURST-DIMPLED (8) \}
|
|
\item {\it opacity} (PDB\_FLOAT)--The opacity of the final blend (0 <= opacity <= 100)
|
|
\item {\it offset} (PDB\_FLOAT)--Offset relates to the starting and ending coordinates specified for the blend. This parameter is mode depndent (0 <= offset)
|
|
\item {\it repeat} (PDB\_INT32)--Repeat the gradient indefinitely along the direction vector
|
|
\item {\it x1} (PDB\_FLOAT)--The x coordinate of this blend's starting point
|
|
\item {\it y1} (PDB\_FLOAT)--The y coordinate of this blend's starting point
|
|
\item {\it x2} (PDB\_FLOAT)--The x coordinate of this blend's ending point
|
|
\item {\it y2} (PDB\_FLOAT)--The y coordinate of this blend's ending point
|
|
\end{itemize}}
|
|
\end{itemize}
|
|
\onecolumn
|
|
|
|
\section{Script-Fu Logos}
|
|
|
|
Plates 1-4 are example outputs of Script-Fu scripts:
|
|
\begin{itemize}
|
|
\item {\bf Carve-It}
|
|
\begin{itemize}
|
|
\item {\bf Image}:
|
|
http://scheme.xcf.berkeley.edu/net-fu/images/plates1-2.jpg
|
|
\item {\bf Script}:
|
|
http://scheme.xcf.berkeley.edu/net-fu/scripts/carve.scm
|
|
\item {\bf Net-Fu Logo}:
|
|
http://scheme.xcf.berkeley.edu/net-fu/carve.html
|
|
\end{itemize}
|
|
\item {\bf Starscape Nova}
|
|
\begin{itemize}
|
|
\item {\bf Image}:
|
|
http://scheme.xcf.berkeley.edu/net-fu/images/plates1-2.jpg
|
|
\item {\bf Script}:
|
|
http://scheme.xcf.berkeley.edu/net-fu/scripts/starscape.scm
|
|
\item {\bf Net-Fu Logo}:
|
|
http://scheme.xcf.berkeley.edu/net-fu/starscape.html
|
|
\end{itemize}
|
|
\item {\bf Chrome}
|
|
\begin{itemize}
|
|
\item {\bf Image}:
|
|
http://scheme.xcf.berkeley.edu/net-fu/images/plates3-4.jpg
|
|
\item {\bf Script}:
|
|
http://scheme.xcf.berkeley.edu/net-fu/scripts/chrome2.scm
|
|
\item {\bf Net-Fu Logo}:
|
|
http://scheme.xcf.berkeley.edu/net-fu/chrome2.html
|
|
\end{itemize}
|
|
\item {\bf Crystal/Gel}
|
|
\begin{itemize}
|
|
\item {\bf Image}:
|
|
http://scheme.xcf.berkeley.edu/net-fu/images/plates3-4.jpg
|
|
\item {\bf Script}:
|
|
http://scheme.xcf.berkeley.edu/net-fu/scripts/crystal.scm
|
|
\item {\bf Net-Fu Logo}:
|
|
http://scheme.xcf.berkeley.edu/net-fu/crystal.html
|
|
\end{itemize}
|
|
\end{itemize}
|
|
|
|
\section{Net-Fu WWW Interface}
|
|
|
|
{\bf http://scheme.xcf.berkeley.edu/net-fu/}
|
|
|
|
\end{document}
|