2745 lines
98 KiB
HTML
Executable File
2745 lines
98 KiB
HTML
Executable File
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||
<html>
|
||
<head>
|
||
<title>Lua-GD Reference Manual</title>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||
<style type="text/css">
|
||
<!--
|
||
H1 {
|
||
font-family: Verdana, Arial, helvetica, sans-serif;
|
||
font-size: 20px;
|
||
color: #000000;
|
||
background-color: #FFFFFF;
|
||
text-align: center;
|
||
}
|
||
|
||
H2 {
|
||
font-family: Verdana, Arial, helvetica, sans-serif;
|
||
font-size: 18px;
|
||
color: #000000;
|
||
background-color: #EAEAEA;
|
||
}
|
||
|
||
H3 {
|
||
font-family: Verdana, Arial, helvetica, sans-serif;
|
||
font-size: 16px;
|
||
color: #000000;
|
||
background-color: #EAEAEA;
|
||
}
|
||
|
||
H4 {
|
||
font-family: Verdana, Arial, helvetica, sans-serif;
|
||
font-size: 14px;
|
||
color: #000000;
|
||
}
|
||
|
||
BODY {
|
||
font-family: Verdana, Arial, helvetica, sans-serif;
|
||
font-size: 12px;
|
||
color: #000000;
|
||
background: #FFFFFF;
|
||
}
|
||
|
||
A {
|
||
font-family: Verdana, Arial, helvetica, sans-serif;
|
||
font-size: 12px;
|
||
color: #000088;
|
||
text-decoration: none;
|
||
}
|
||
|
||
A:HOVER {
|
||
text-decoration: underline;
|
||
color: #FF0000;
|
||
background-color: #EAEAEA;
|
||
}
|
||
|
||
HR {
|
||
border: 1px solid #EAEAEA;
|
||
}
|
||
|
||
TABLE {
|
||
border: 0px;
|
||
}
|
||
|
||
TR, TD {
|
||
font-family: Verdana, Arial, helvetica, sans-serif;
|
||
font-size: 12px;
|
||
border: 1px solid #EAEAEA;
|
||
background-color: #FFFFFF;
|
||
padding: 0px;
|
||
cell-spacing: 1px;
|
||
}
|
||
|
||
TR.h, TD.h {
|
||
text-align: center;
|
||
font-weight: bold;
|
||
}
|
||
|
||
TR.i, TD.i {
|
||
text-align: center;
|
||
}
|
||
|
||
TR.n, TD.n {
|
||
font-size: 12px;
|
||
font-family: "Courier New", courier, monospace;
|
||
}
|
||
|
||
|
||
pre
|
||
{
|
||
font-family: "Courier New", courier, monospace;
|
||
color: black;
|
||
}
|
||
|
||
pre.example
|
||
{
|
||
border: 1px solid rgb(128, 128, 128);
|
||
padding: 5pt;
|
||
display: block;
|
||
font-family: "Courier New", courier, monospace;
|
||
background-color: #F0F0F0;
|
||
margin-left: 2%;
|
||
margin-right: 2%;
|
||
}
|
||
|
||
pre.example2
|
||
{
|
||
border: 1px solid rgb(128, 128, 128);
|
||
padding: 5pt;
|
||
display: block;
|
||
font-family: "Courier New", courier, monospace;
|
||
background-color: #F0F0F0;
|
||
}
|
||
|
||
pre.wrong
|
||
{
|
||
border: gray 1pt solid;
|
||
padding: 2pt;
|
||
display: block;
|
||
font-family: "Courier New", courier, monospace;
|
||
background-color: #FF0000;
|
||
color: black;
|
||
}
|
||
|
||
-->
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
|
||
<center>
|
||
<a href="http://lua-gd.luaforge.net"
|
||
><img src="lua-gd.png" alt="Lua-GD Logo" title="Lua-GD Logo" border="0"></a>
|
||
<h1>Lua-GD 2.0.33r2</h1>
|
||
</center>
|
||
|
||
<h2> Contents </h2>
|
||
<ul>
|
||
<li><a href="#intro">Introduction</a>
|
||
<li><a href="#license">Licensing information</a>
|
||
<ul>
|
||
<li><a href="#license.luagd">Lua-GD License</a></li>
|
||
<li><a href="#license.gd">gd License</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#download">Download and installation</a></li>
|
||
<li><a href="#load">Library loading and initialization</a></li>
|
||
<li><a href="#api">Lua-GD API</a>
|
||
<ul>
|
||
<li><a href="#api.constants">Constants</a></li>
|
||
<li><a href="#api.create">Image creation functions</a></li>
|
||
<li><a href="#api.input">Image input functions</a></li>
|
||
<li><a href="#api.output">Image output methods</a></li>
|
||
<li><a href="#api.color">Color manipulation methods</a></li>
|
||
<li><a href="#api.draw">Query methods</a></li>
|
||
<li><a href="#api.draw">Drawing methods</a></li>
|
||
<li><a href="#api.text">Text drawing methods</a></li>
|
||
<li><a href="#api.font">Font configuration methods</a></li>
|
||
<li><a href="#api.copy">Copying and resizing methods</a></li>
|
||
<li><a href="#api.gifanim">GIF animation methods</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#examples">Examples</a>
|
||
<ul>
|
||
<li><a href="#examples.counter">CGI Web Counter</a></li>
|
||
<li><a href="#examples.clock">CGI Analog Clock</a></li>
|
||
<li><a href="#examples.fractal">The Sierpinski triangle</a></li>
|
||
<li><a href="#examples.fontconfig">Using Freetype, Fontconfig and TrueType fonts</a></li>
|
||
<li><a href="#examples.gifanim">GIF animation</a></li>
|
||
<li><a href="#examples.steg">A Steganography Application</a></li>
|
||
<li><a href="#examples.other">Other examples</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#contact">Contact information</a></li>
|
||
</ul>
|
||
|
||
|
||
<a name="intro"></a>
|
||
<h2>Introduction</h2>
|
||
|
||
<p> "gd" is a C graphics library created by
|
||
<a href="http://www.boutell.com/contact">Thomas Boutell</a> that allows
|
||
your code to quickly draw complete images with lines, polygons, arcs,
|
||
text, multiple colors, cut and paste from other images, flood fills,
|
||
read in or write out images in the PNG, JPEG or GIF format. This is
|
||
particularly useful in World Wide Web applications, where PNG and JPEG are
|
||
two of the formats accepted for inline images by most browsers. gd does
|
||
not provide for every possible desirable graphics operation. It is not
|
||
necessary or desirable for gd to become a kitchen-sink graphics package,
|
||
but it does include most frequently requested features, including both
|
||
truecolor and palette images, resampling (smooth resizing of truecolor
|
||
images) and so forth. You can get more information about gd from <a
|
||
href="http://www.boutell.com/gd/">it's homepage</a>. </p>
|
||
|
||
<p> Lua-GD is a "binding": a library that exports gd functions to the <a
|
||
href="http://www.lua.org">Lua Programming Language</a>, allowing you to
|
||
use gd from Lua. The API was <b>NOT</b> literally exported, but changed
|
||
in a way that make it familiar to Lua users. </p>
|
||
|
||
<p> Lua-GD is a programming library, not a paint program. If you are
|
||
looking for that or are not familiar to the Lua Programming Language,
|
||
you are in the wrong place. </p>
|
||
|
||
<p> This document, which was heavly based on gd manual, describes the API
|
||
and provides the information needed to use the library. Some experience
|
||
with Lua is <b>required</b>.</p>
|
||
|
||
<p><b>A NOTE ON VERSION NUMBERS:</b> Lua-GD version numbers is in
|
||
the format "X.Y.ZrW", where X.Y.Z indicates the gd version and W the
|
||
binding version. So, the <b>2.0.33r1</b> version is the first binding
|
||
version for gd 2.0.33 and <b>2.0.33r2</b> has some improvements/bug
|
||
fixes/etc. but uses the same gd version. </p>
|
||
|
||
|
||
|
||
<a name="license"></a>
|
||
<h2>Licensing information</h2>
|
||
|
||
<p> Lua-GD and gd have diferent licenses. In order to use Lua-GD in your
|
||
application, you need to accept both them. </p>
|
||
|
||
<a name="license.luagd"></a>
|
||
<h3>Lua-GD License</h3>
|
||
|
||
<p>Lua-GD is <em>copyrighted free software</em>, distributed under the
|
||
MIT license (the same used by Lua 5.1) and it can be used at no cost for
|
||
both academic and commercial purpouses. Or, more precisely: </p>
|
||
|
||
<blockquote>
|
||
<pre>
|
||
Lua-GD (c) 2004-2006 Alexandre Erwin Ittner
|
||
|
||
Permission is hereby granted, free of charge, to any person obtaining
|
||
a copy of this software and associated documentation files (the
|
||
"Software"), to deal in the Software without restriction, including
|
||
without limitation the rights to use, copy, modify, merge, publish,
|
||
distribute, sublicense, and/or sell copies of the Software, and to
|
||
permit persons to whom the Software is furnished to do so, subject to
|
||
the following conditions:
|
||
|
||
The above copyright notice and this permission notice shall be
|
||
included in all copies or substantial portions of the Software.
|
||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||
IN NO EVENT SHALL THE AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
||
If you use this package in a product, an acknowledgment in the product
|
||
documentation would be greatly appreciated (but it is not required).
|
||
</pre>
|
||
</blockquote>
|
||
|
||
|
||
<a name="license.gd"></a>
|
||
<h3>gd License</h3>
|
||
|
||
<blockquote>
|
||
<p>Portions copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||
2002, 2003, 2004 by Cold Spring Harbor Laboratory. Funded under Grant
|
||
P41-RR02188 by the National Institutes of Health.</p>
|
||
|
||
<p>Portions copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
|
||
2004 by Boutell.Com, Inc.</p>
|
||
|
||
<p>Portions relating to GD2 format copyright 1999, 2000, 2001, 2002,
|
||
2003, 2004 Philip Warner.</p>
|
||
|
||
<p>Portions relating to PNG copyright 1999, 2000, 2001, 2002, 2003,
|
||
2004 Greg Roelofs.</p>
|
||
|
||
<p>Portions relating to gdttf.c copyright 1999, 2000, 2001, 2002, 2003,
|
||
2004 John Ellson (ellson@graphviz.org).</p>
|
||
|
||
<p>Portions relating to gdft.c copyright 2001, 2002, 2003, 2004 John
|
||
Ellson (ellson@graphviz.org).</p>
|
||
|
||
<p>Portions relating to JPEG and to color quantization copyright 2000,
|
||
2001, 2002, 2003, 2004, Doug Becker and copyright (C) 1994, 1995, 1996,
|
||
1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Thomas G. Lane. This
|
||
software is based in part on the work of the Independent JPEG Group. See
|
||
the file README-JPEG.TXT for more information.</p>
|
||
|
||
<p>Portions relating to GIF compression copyright 1989 by Jef Poskanzer
|
||
and David Rowley, with modifications for thread safety by Thomas
|
||
Boutell.</p>
|
||
|
||
<p>Portions relating to GIF decompression copyright 1990, 1991, 1993 by
|
||
David Koblas, with modifications for thread safety by Thomas Boutell.</p>
|
||
|
||
<p>Portions relating to WBMP copyright 2000, 2001, 2002, 2003, 2004
|
||
Maurice Szmurlo and Johan Van den Brande.</p>
|
||
|
||
<p>Portions relating to GIF animations copyright 2004 Jaakko Hyv<79>tti
|
||
(jaakko.hyvatti@iki.fi)</p>
|
||
|
||
<p>Permission has been granted to copy, distribute and modify gd in any
|
||
context without fee, including a commercial application, provided that
|
||
this notice is present in user-accessible supporting documentation.</p>
|
||
|
||
<p>This does not affect your ownership of the derived work itself, and the
|
||
intent is to assure proper credit for the authors of gd, not to interfere
|
||
with your productive use of gd. If you have questions, ask. "Derived
|
||
works" includes all programs that utilize the library. Credit must be
|
||
given in user-accessible documentation.</p>
|
||
|
||
<p>This software is provided "AS IS." The copyright holders disclaim
|
||
all warranties, either express or implied, including but not limited
|
||
to implied warranties of merchantability and fitness for a particular
|
||
purpose, with respect to this code and accompanying documentation.</p>
|
||
|
||
<p>Although their code does not appear in the current release, the
|
||
authors also wish to thank Hutchison Avenue Software Corporation for
|
||
their prior contributions. </p>
|
||
|
||
</blockquote>
|
||
|
||
|
||
|
||
|
||
|
||
<a name="download"></a>
|
||
<a name="installation"></a>
|
||
<h2>Download and installation</h2>
|
||
|
||
<p> Lua-GD source code comes in a tar.gz package that can be downloaded
|
||
from the <a href="http://luaforge.net/projects/lua-gd/">Lua-GD project
|
||
page</a> on <a href="http://www.luaforge.net">LuaForge</a> or from
|
||
its <a href="http://www.sourceforge.net/projects/lua-gd/">mirror on
|
||
Sourceforge</a>. There are also some pre-compiled binary packages
|
||
available for Linux and some other Unix systems.</p>
|
||
|
||
<p> After downloading, you need to compile the library. This process
|
||
requires GNU Make, gd and its dependencies (libpng, libjpeg, FreeType2,
|
||
fontconfig, etc.) installed on your system. Some components that may
|
||
be disabled on your gd installation will be disabled in Lua-GD too. To
|
||
compile on Unix, just unpack the distribution package, enter the directory
|
||
and type <code>make</code> in your favourite shell. If the compilation
|
||
was successful, you will see something like: </p>
|
||
|
||
<pre>
|
||
gcc -o gd.so `gdlib-config --features |sed -e "s/GD_/-DGD_/g"`
|
||
`gdlib-config --cflags` `pkg-config lua5.1 --cflags` -O3 -Wall -shared
|
||
`gdlib-config --ldflags` `gdlib-config --libs` `pkg-config lua5.1 --libs`
|
||
-lgd luagd.c
|
||
lua test_features.lua
|
||
Lua-GD version: lua-gd 2.0.33r2
|
||
Lua-GD features:
|
||
PNG support ..................... Enabled
|
||
GIF support ..................... Enabled
|
||
JPEG support .................... Enabled
|
||
XPM/XBM support ................. Enabled
|
||
FreeType support ................ Enabled
|
||
Fontconfig support .............. Enabled
|
||
</pre>
|
||
|
||
<p> To install the library with <b>Lua 5.1</b> and above just type
|
||
<code>make install</code>, as root. </p>
|
||
|
||
<p> <b> WARNING:</b> This will work only in systems with pkg-config (which
|
||
includes the major Linux distributions). In other systems, you will need to
|
||
edit the Makefile and manually install the library, by copying the 'gd.so'
|
||
file to your Lua binary modules directory.</p>
|
||
|
||
<p> Compiling Lua-GD on Windows systems is almost, but not quite,
|
||
entirely unlike compiling it on Unix. You will need to edit the Makefile
|
||
by yourself. </p>
|
||
|
||
<p> <b>A NOTE TO DEBIAN/UBUNTU USERS:</b> To enable the Fontconfig and XPM
|
||
support, you will need the <b>libgd2-xpm</b> and <b>libgd2-xpm-dev</b>
|
||
packages. The <b>libgd2-noxpm</b> does not have Fontconfig support.</p>
|
||
|
||
|
||
|
||
<a name="load"></a>
|
||
<h2>Library loading and initialization</h2>
|
||
|
||
<p>Lua-GD uses the Lua 5.1 package system that allows you to simply do a</p>
|
||
|
||
<pre class="example">require "gd"</pre>
|
||
|
||
<p> call to load up the library. </p>
|
||
|
||
|
||
|
||
|
||
<a name="api"></a>
|
||
<h2>Lua-GD API</h2>
|
||
|
||
<p> The Lua-GD API is not identical to the gd C API: it was changed in
|
||
a way that make it more familiar to Lua users and use the extra power
|
||
provided by Lua, at cost of some learning for those that already use
|
||
gd. </p>
|
||
|
||
<p> All the functions and constants are stored on a single global
|
||
module called <code>gd</code>. Images are objects and they can use the
|
||
common colon notation for its methods, but you can also use a C-style
|
||
syntax. So, the following two lines are equivalent: </p>
|
||
|
||
<pre class="example">
|
||
local gray1 = im:colorResolve(128, 128, 128) -- Using the colon notation
|
||
local gray2 = gd.colorResolve(im, 128, 128, 128) -- Using a C-style notation
|
||
</pre>
|
||
|
||
<p> Constants, functions and methods are described bellow.</p>
|
||
|
||
|
||
|
||
<a name="api.constants"></a>
|
||
<h3>Constants</h3>
|
||
|
||
<h4>gd.VERSION</h4>
|
||
<p>A string with the version and some information about the library.</p>
|
||
|
||
<h4> gd.MAX_COLORS </h4>
|
||
<p>The constant 256. This is the maximum number of colors in a
|
||
palette-based PNG file according to the PNG standard, and is also the
|
||
maximum number of colors in a palette-based gd image. This of course
|
||
does not apply to truecolor images.</p>
|
||
|
||
<h4> gd.GD2_FMT_RAW <br>
|
||
gd.GD2_FMT_COMPRESSED</h4>
|
||
|
||
<p> Used when saving images to GD2 files with <code>gd2</code> and
|
||
<code>gd2Str</code> to indicate the image file format. This format is not
|
||
intended for general purpose use and should never be used to distribute
|
||
images. It is a file format allowing pseudo-random access to large
|
||
image files. Its purpose is solely to allow very fast loading of parts
|
||
of images. You should use <code>GD2_FMT_RAW</code> for faster loading
|
||
(and bigger files) or GD2_FMT_COMPRESSED for smaller files (and slower
|
||
loading). </p>
|
||
|
||
|
||
<h4> gd.ARC <br>
|
||
gd.CHORD <br>
|
||
gd.PIE <br>
|
||
gd.NO_FILL <br>
|
||
gd.EDGED </h4>
|
||
|
||
<p> These constants are used with the method <code>filledArc</code>
|
||
and can be added together. <code>gd.ARC</code>, <code>gd.CHORD</code>,
|
||
<code>gd.PIE</code> (synonym for <code>gd.CHORD</code>),
|
||
<code>gd.NO_FILL</code> and <code>gd.EDGED</code> are mutually
|
||
exclusive; <code>gd.CHORD</code> just connects the starting and
|
||
ending angles with a straight line, while <code>gd.ARC</code>
|
||
produces a rounded edge. <code>gd.PIE</code> is a synonym for
|
||
<code>gd.ARC</code>. <code>gd.NO_FILL</code> indicates that the arc
|
||
or chord should be outlined, not filled. <code>gd.EDGED</code>, used
|
||
together with <code>gd.NO_FILL</code>, indicates that the beginning and
|
||
ending angles should be connected to the center; this is a good way to
|
||
outline (rather than fill) a 'pie slice'. See <code>gd.filledArc</code>
|
||
for details.</p>
|
||
|
||
|
||
<h4>gd.ANTI_ALIASED</h4>
|
||
|
||
<p>Used in place of a color when invoking a line-drawing method
|
||
such as <code>gd.line</code> or <code>gd.rectangle</code>. When
|
||
<code>gd.ANTI_ALIASED</code> is used as the color, the foreground color
|
||
set with <code>gd.setAntiAliased</code> is used, with antialiasing
|
||
mechanisms to minimize any "jagged" appearance. For more information,
|
||
see <code>gd.setAntiAliased</code>.</p>
|
||
|
||
|
||
<h4>gd.BRUSHED</h4>
|
||
|
||
<p>Used in place of a color when invoking a line-drawing method
|
||
such as <code>gd.line</code> or <code>gd.rectangle</code>. When
|
||
<code>gd.BRUSHED</code> is used as the color, the brush image set with
|
||
<code>gd.setBrush</code> is drawn in place of each pixel of the line
|
||
(the brush is usually larger than one pixel, creating the effect of a
|
||
wide paintbrush). See also <code>gd.STYLED_BRUSHED</code> for a way to
|
||
draw broken lines with a series of distinct copies of an image. </p>
|
||
|
||
|
||
<h4>gd.STYLED</h4>
|
||
|
||
<p> Used in place of a color when invoking a line-drawing method
|
||
such as <code>gd.line</code> or <code>gd.rectangle</code>. When
|
||
<code>gd.STYLED</code> is used as the color, the colors of the
|
||
pixels are drawn successively from the style that has been set
|
||
with <code>gd.setStyle</code>. If the color of a pixel is equal to
|
||
<code>gd.TRANSPARENT</code>, that pixel is not altered. (This mechanism
|
||
is completely unrelated to the "transparent color" of the image itself;
|
||
see <code>gd.colorTransparent</code> for that mechanism). </p>
|
||
|
||
|
||
<h4>gd.STYLED_BRUSHED</h4>
|
||
|
||
<p> Used in place of a color when invoking a line-drawing method
|
||
such as <code>gd.line</code> or <code>gd.rectangle</code>. When
|
||
<code>gd.STYLED_BRUSHED</code> is used as the color, the brush image
|
||
set with <code>gd.setBrush</code> is drawn at each pixel of the line,
|
||
providing that the style set with <code>gd.setStyle</code> contains
|
||
a nonzero value (OR <code>gd.TRANSPARENT</code>, which does not equal
|
||
zero but is supported for consistency) for the current pixel. (Pixels
|
||
are drawn successively from the style as the line is drawn, returning to
|
||
the beginning when the available pixels in the style are exhausted). Note
|
||
that this differs from the behavior of <code>gd.STYLED</code>, in which
|
||
the values in the style are used as actual pixel colors, except for
|
||
<code>gd.TRANSPARENT</code>. </p>
|
||
|
||
|
||
<h4>gd.TILED</h4>
|
||
|
||
<p> Used in place of a normal color in <code>gd.filledRectangle</code>,
|
||
<code>gd.filledPolygon</code>, <code>gd.fill</code>, and
|
||
<code>gd.fillToBorder</code>. <code>gd.TILED</code>
|
||
selects a pixel from the tile image set with <code>gd.setTile</code>
|
||
in such a way as to ensure that the filled area will be tiled with
|
||
copies of the tile image. See the discussions of <code>gd.fill</code>
|
||
and <code>gd.fillToBorder</code> for special restrictions regarding
|
||
those methods. </p>
|
||
|
||
|
||
<h4>gd.TRANSPARENT</h4>
|
||
|
||
<p> Used in place of a normal color in a style to be set with
|
||
<code>gd.setStyle</code>. <code>gd.TRANSPARENT</code> <b>is not</b>
|
||
the transparent color index of the image; for that functionality please
|
||
see <code>gd.colorTransparent</code>. </p>
|
||
|
||
|
||
<h4> gd.FONT_TINY <br>
|
||
gd.FONT_SMALL <br>
|
||
gd.FONT_MEDIUM <br>
|
||
gd.FONT_LARGE <br>
|
||
gd.FONT_GIANT </h4>
|
||
|
||
<p> These are the standard gd fonts used by <code>gd.string</code> and
|
||
<code>gd.stringUp</code>. Sizes and styles are shown bellow: <br>
|
||
|
||
<img src="stdfonts.png" width="140" height="110" alt="Standard gd fonts"
|
||
title="Standard gd fonts">
|
||
|
||
<br> If you need another fonts, you should use TrueType fonts with
|
||
<code>gd.stringFT</code>.
|
||
</p>
|
||
|
||
<h4> gd.FTEX_Unicode <br>
|
||
gd.FTEX_Shift_JIS <br>
|
||
gd.FTEX_Big5 </h4>
|
||
|
||
<p> These are the character maps used by <code>gd.stringFTEx</code>. Explicit
|
||
specification of the desired character mapping is useful when a font offers
|
||
more than one of Unicode, Shift_JIS, and Big5. </p>
|
||
|
||
|
||
<a name="api.create"></a>
|
||
<h3>Image creation and destruction</h3>
|
||
|
||
|
||
<h4> gd.create(x, sy) <br>
|
||
gd.createPalette(x, y) </h4>
|
||
|
||
<p> These functions are used to create palette-based images, with
|
||
no more than 256 colors. Invoke <code>gd.create</code> with the x
|
||
and y dimensions of the desired image to return the new image or
|
||
<b>nil</b> on error. <code>gd.createPalette</code> is a synomym for
|
||
<code>gd.create</code>. </p>
|
||
|
||
<p>Example:</p>
|
||
|
||
<pre class="example">
|
||
-- creates a 20x20px palette-based image
|
||
local im = gd.create(20, 20)
|
||
</pre>
|
||
|
||
<p>You don't need to destroy an image by yourself. Lua has a garbage
|
||
collector that detects when an piece of information becomes useless and
|
||
"automagically" removes it from memory. </p>
|
||
|
||
|
||
<h4>gd.createTrueColor(x, y)</h4>
|
||
|
||
<p> Used to create truecolor images, with an essentially unlimited
|
||
number of colors. Invoke <code>gd.createTrueColor</code> with the x and
|
||
y dimensions of the desired image to return the new image or <b>nil</b>
|
||
on error. Truecolor images are always filled with black at creation
|
||
time. There is no concept of a "background" color index. </p>
|
||
|
||
<p>Example:</p>
|
||
<pre class="example">
|
||
-- creates a 20x20px true color image
|
||
local im = gd.createTrueColor(20, 20)
|
||
</pre>
|
||
|
||
<p>You don't need to destroy an image by yourself. Lua has a garbage
|
||
collector that detects when an piece of information becomes useless and
|
||
"automagically" deletes it from memory. </p>
|
||
|
||
|
||
|
||
<h4>gdImage:createPaletteFromTrueColor(dither, colorsWanted)</h4>
|
||
|
||
<p> This method creates a new palette-based image from a truecolor
|
||
image using a high-quality two-pass quantization routine. If
|
||
the <b>dither</b> flag is set to <b>true</b>, the image will be
|
||
dithered to approximate colors better, at the expense of some obvious
|
||
"speckling". <b>colorsWanted</b>, an integer value, can be anything up
|
||
to 256. If the original source image includes photographic information
|
||
or anything that came out of a JPEG, 256 is strongly recommended. 100%
|
||
transparency of a single transparent color in the original truecolor
|
||
image will be preserved. There is no other support for preservation of
|
||
alpha channel or transparency in the destination image. </p>
|
||
|
||
<p> For best results, don't use this method -- write real truecolor
|
||
PNGs and JPEGs. The disk space gain of conversion to palette is not great
|
||
(for small images it can be negative) and the quality loss is ugly. </p>
|
||
|
||
|
||
|
||
|
||
<a name="api.input"></a>
|
||
<h3>Image input functions</h3>
|
||
|
||
|
||
|
||
<h4>gd.createFromJpeg(filename)</h4>
|
||
|
||
<p> <code>gd.createFromJpeg</code> is called to load truecolor images from
|
||
JPEG format files. Invoke <code>gd.createFromJpeg</code> with a string
|
||
pointing to an existing file containing the desired image to return a new
|
||
truecolor image or <b>nil</b> if unable to load the image (most often
|
||
because the file is corrupt or does not contain a JPEG image). You can
|
||
determine the size of the image with <code>gd.sizeXY</code>. The returned
|
||
image is always a truecolor image. </p>
|
||
|
||
|
||
|
||
<h4>gd.createFromPng(filename)</h4>
|
||
|
||
<p> <code>gd.createFromPng</code> is called to load images from PNG format
|
||
files. Invoke <code>gd.createFromPng</code> with a string pointing to
|
||
an existing file containing the desired image to return a new image or
|
||
<b>nil</b> if unable to load the image (most often because the file is
|
||
corrupt or does not contain a PNG image). You can determine the size of
|
||
the image with <code>gd.sizeXY</code>. </p>
|
||
|
||
<p> If the PNG image being loaded is a truecolor image, the resulting
|
||
value will refer to a truecolor image. If the PNG image being loaded
|
||
is a palette or grayscale image, the resulting data will refer to a
|
||
palette image. gd retains only 8 bits of resolution for each of the red,
|
||
green and blue channels, and only 7 bits of resolution for the alpha
|
||
channel. The former restriction affects only a handful of very rare
|
||
48-bit color and 16-bit grayscale PNG images. The second restriction
|
||
affects all semitransparent PNG images, but the difference is essentially
|
||
invisible to the eye. 7 bits of alpha channel resolution is, in practice,
|
||
quite a lot. </p>
|
||
|
||
<p>Example:</p>
|
||
<pre class="example">
|
||
-- copies the content of picture.png to a new image
|
||
local im = gd.createFromPng("picture.png")
|
||
</pre>
|
||
|
||
|
||
<h4>gd.createFromGif(filename)</h4>
|
||
|
||
<p> <code>gd.createFromGif</code> is called to load images from GIF format
|
||
files. Invoke <code>gd.createFromGif</code> with a string pointing to
|
||
an existing file containing the desired image to return a new image or
|
||
<b>nil</b> if unable to load the image (most often because the file is
|
||
corrupt or does not contain a GIF image). You can determine the size of
|
||
the image with <code>gd.sizeXY</code>. </p>
|
||
|
||
|
||
<h4>gd.createFromGd(filename)</h4>
|
||
|
||
<p> <code>gd.createFromGd</code> is called to load images from gd format
|
||
files. Invoke <code>gd.createFromGd</code> with a string pointing to
|
||
an existing file containing the desired image to return a new image or
|
||
<b>nil</b> if unable to load the image (most often because the file is
|
||
corrupt or does not contain a gd image). You can determine the size of
|
||
the image with <code>gd.sizeXY</code>. This format is not intended for
|
||
general purpose use and should never be used to distribute images. Its
|
||
purpose is solely to allow very fast loading of images. </p>
|
||
|
||
|
||
<h4>gd.createFromGd2(filename)</h4>
|
||
|
||
<p> <code>gd.createFromGd2</code> is called to load images from gd2 format
|
||
files. Invoke <code>gd.createFromGd2</code> with a string pointing to
|
||
an existing file containing the desired image to return a new image or
|
||
<b>nil</b> if unable to load the image (most often because the file is
|
||
corrupt or does not contain a gd2 image). You can determine the size of
|
||
the image with <code>gd.sizeXY</code>. This format is not intended for
|
||
general purpose use and should never be used to distribute images. Its
|
||
purpose is solely to allow very fast loading of images. </p>
|
||
|
||
|
||
<h4>gd.createFromGd2Part(filename, x, y, w, h)</h4>
|
||
|
||
<p> <code>gd.createFromGd2Part</code> is called to load parts
|
||
of images from gd2 format files. Invoked in the same way as
|
||
<code>gd.createFromGd2</code>, but with extra parameters indicating the
|
||
source (x, y) and width/height of the desired image. </p>
|
||
|
||
<p>Example:</p>
|
||
<pre class="example">
|
||
-- Being base.gd2 a 40x40px image, copies its upper-left part to a new image
|
||
local im = gd.createFromGd2Part("base.gd2", 0, 0, 20, 20)
|
||
</pre>
|
||
|
||
|
||
<h4>gd.createFromXbm(filename)</h4>
|
||
|
||
<p> <code>gd.createFromXbm</code> is called to load images from
|
||
monochromatic X bitmap format files. Invoke <code>gd.createFromXbm</code>
|
||
with a string pointing to an existing file containing the desired image
|
||
to return a new image or <b>nil</b> if unable to load the image (most
|
||
often because the file is corrupt or does not contain a XBM image). You
|
||
can determine the size of the image with <code>gd.sizeXY</code>. </p>
|
||
|
||
|
||
<h4>gd.createFromXpm(filename)</h4>
|
||
|
||
<p> <code>gd.createFromXpm</code> is called to load images from color X
|
||
bitmap format files. Invoke <code>gd.createFromXpm</code> with a string
|
||
pointing to an existing file containing the desired image to return a
|
||
new image or <b>nil</b> if unable to load the image (most often because
|
||
the file is corrupt or does not contain a XPM image). You can determine
|
||
the size of the image with <code>gd.sizeXY</code>. </p>
|
||
|
||
|
||
<h4>gd.createFromJpegStr(string)</h4>
|
||
|
||
<p> <code>gd.createFromJpegStr</code> is called to load
|
||
truecolor images from strings with JPEG format image data. Invoke
|
||
<code>gd.createFromJpegStr</code> passing a string with the desired
|
||
image to return a new truecolor image or <b>nil</b> if unable to
|
||
load the image (most often because the data is corrupt or does not
|
||
contain a JPEG image). You can determine the size of the image with
|
||
<code>gd.sizeXY</code>. The returned image is always a truecolor
|
||
image. </p>
|
||
|
||
|
||
<h4>gd.createFromGifStr(string)</h4>
|
||
|
||
<p> <code>gd.createFromGifStr</code> is called to load
|
||
palette-based images from strings with GIF format image data. Invoke
|
||
<code>gd.createFromGifStr</code> passing a string with the desired image
|
||
to return a new image or <b>nil</b> if unable to load the image (most
|
||
often because the data is corrupt or does not contain a GIF image). You
|
||
can determine the size of the image with <code>gd.sizeXY</code>. </p>
|
||
|
||
|
||
<h4>gd.createFromPngStr(string)</h4>
|
||
|
||
<p> <code>gd.createFromPngStr</code> is called to load images from strings
|
||
with PNG format image data. Invoke <code>gd.createFromPngStr</code>
|
||
passing a string with the desired image to return a new image or
|
||
<b>nil</b> if unable to load the image (most often because the data is
|
||
corrupt or does not contain a PNG image). You can determine the size of
|
||
the image with <code>gd.sizeXY</code>. </p>
|
||
|
||
<p> If the PNG image being loaded is a truecolor image, the resulting
|
||
value will refer to a truecolor image. If the PNG image being loaded
|
||
is a palette or grayscale image, the resulting data will refer to a
|
||
palette image. gd retains only 8 bits of resolution for each of the red,
|
||
green and blue channels, and only 7 bits of resolution for the alpha
|
||
channel. The former restriction affects only a handful of very rare
|
||
48-bit color and 16-bit grayscale PNG images. The second restriction
|
||
affects all semitransparent PNG images, but the difference is essentially
|
||
invisible to the eye. 7 bits of alpha channel resolution is, in practice,
|
||
quite a lot. </p>
|
||
|
||
<p>Example:</p>
|
||
|
||
<pre class="example">
|
||
-- reads the contents of the file to a string
|
||
fp = io.open("picture.png")
|
||
str = fp:read("*a")
|
||
fp:close()
|
||
|
||
-- creates an image from the string
|
||
local im = gd.createFromPngStr(str)
|
||
</pre>
|
||
|
||
|
||
<h4>gd.createFromGdStr(string)</h4>
|
||
|
||
<p> <code>gd.createFromGdStr</code> is called to load images from strings
|
||
with gd format image data. Invoke <code>gd.createFromGdStr</code> passing
|
||
a string with the desired image to return a new image or <b>nil</b>
|
||
if unable to load the image (most often because the data is corrupt or
|
||
does not contain a gd image). You can determine the size of the image
|
||
with <code>gd.sizeXY</code>. This format is not intended for general
|
||
purpose use and should never be used to distribute images. Its purpose
|
||
is solely to allow very fast loading of images. </p>
|
||
|
||
|
||
<h4>gd.createFromGd2Str(string)</h4>
|
||
|
||
<p> <code>gd.createFromGd2Str</code> is called to load images from strings
|
||
with gd2 format image data. Invoke <code>gd.createFromGd2Str</code>
|
||
passing a string with the desired image to return a new image or
|
||
<b>nil</b> if unable to load the image (most often because the data is
|
||
corrupt or does not contain a gd2 image). You can determine the size of
|
||
the image with <code>gd.sizeXY</code>. This format is not intended for
|
||
general purpose use and should never be used to distribute images. Its
|
||
purpose is solely to allow very fast loading of images. </p>
|
||
|
||
|
||
<h4>gd.createFromGd2PartStr(string, x, y, w, h)</h4>
|
||
|
||
<p> <code>gd.createFromGd2PartStr</code> is called to load parts
|
||
of images from gd2 format strings. Invoked in the same way as
|
||
<code>gd.createFromGd2Str</code>, but with extra parameters indicating
|
||
the source (x, y) and width/height of the desired image. </p>
|
||
|
||
|
||
<a name="api.output"></a>
|
||
<h3>Image output methods</h3>
|
||
|
||
<h4>gdImage:png(filename)</h4>
|
||
|
||
<p> Outputs the image to a PNG file with the specified name (overwriting
|
||
existing files). This method returns <b>false</b> on error (eg. permission
|
||
denied to overwrite an existing file) and <b>true</b> on success. </p>
|
||
|
||
<p>Example:</p>
|
||
|
||
<pre class="example">
|
||
-- creates a new image
|
||
local im = gd.createTrueColor(20, 20)
|
||
|
||
-- ** DO SOME ART HERE **
|
||
|
||
-- writes the image to a PNG file.
|
||
im:png("picture.png")
|
||
</pre>
|
||
|
||
|
||
<p> If you want to check if the writting was succeful:</p>
|
||
<pre class="example">
|
||
-- creates a new image
|
||
local im = gd.createTrueColor(20, 20)
|
||
|
||
-- ** DO SOME ART HERE **
|
||
|
||
if im:png("picture.png") then
|
||
print("Image written to disk")
|
||
else
|
||
print("Oops, an error...")
|
||
end
|
||
</pre>
|
||
|
||
|
||
<h4>gdImage:pngEx(filename, compression_level)</h4>
|
||
|
||
<p> Similiar to <code>gd.png</code>, but allows you to specify the
|
||
compression level of a PNG image, from 1 to 6 (or -1 for the default
|
||
compression level of libpng). This method returns <b>false</b> on error
|
||
(eg. permission denied to overwrite an existing file) and <b>true</b>
|
||
on success. </p>
|
||
|
||
|
||
<h4>gdImage:jpeg(filename, quality)</h4>
|
||
|
||
<p> Outputs the image to a JPEG file with the specified name (overwriting
|
||
existing files). You must specify the quality of the generated JPEG
|
||
file from 1 (worst quality, small files) to 100 (best quality, large
|
||
files). This method returns <b>false</b> on error (eg. permission denied
|
||
to overwrite an existing file) and <b>true</b> on success. </p>
|
||
|
||
|
||
|
||
<h4>gdImage:gif(filename)</h4>
|
||
|
||
<p> Outputs the image to a GIF file with the specified name (overwriting
|
||
existing files). This method returns <b>false</b> on error (eg. permission
|
||
denied to overwrite an existing file) and <b>true</b> on success. </p>
|
||
|
||
|
||
<h4>gdImage:gd(filename)</h4>
|
||
|
||
<p> Outputs the image to a gd format file with the specified name
|
||
(overwriting existing files). This method returns <b>false</b> on error
|
||
(eg. permission denied to overwrite an existing file) and <b>true</b>
|
||
on success. This format is not intended for general purpose use and
|
||
should never be used to distribute images. Its purpose is solely to
|
||
allow very fast loading of images. </p>
|
||
|
||
|
||
<h4>gdImage:gd2(filename, chunkSize, format)</h4>
|
||
|
||
<p> Outputs the image to a gd2 format file with the specified name
|
||
(overwriting existing files). This method returns <b>false</b> on error
|
||
(eg. permission denied to overwrite an existing file) and <b>true</b>
|
||
on success. You must specify the chunk size (an integer, or 0 for the
|
||
default) and the file format, which can be <code>gd.GD2_FMT_RAW</code>
|
||
or <code>gd.GD2_FMT_COMPRESSED</code>. This format is not intended for
|
||
general purpose use and should never be used to distribute images. Its
|
||
purpose is solely to allow very fast loading of images. </p>
|
||
|
||
|
||
<h4>gdImage:wbmp(filename, fg)</h4>
|
||
|
||
<p> Outputs the image to a WBMP file with the specified name (overwriting
|
||
existing files). WBMP file support is black and white only. The color
|
||
index specified by the fg argument is the "foreground", and only pixels
|
||
of this color will be set in the WBMP file. All other pixels will be
|
||
considered "background". This method returns <b>false</b> on error
|
||
(eg. permission denied to overwrite an existing file) and <b>true</b>
|
||
on success. </p>
|
||
|
||
|
||
<h4>gdImage:pngStr()</h4>
|
||
|
||
<p> This method returns the image in the PNG format as a Lua string
|
||
or <b>nil</b> on error (eg. a corrupted image).</p>
|
||
|
||
|
||
<h4>gdImage:pngStrEx(compression_level)</h4>
|
||
|
||
<p> Similiar to <code>gd.pngStr</code>, but allows you to specify the
|
||
compression level of a PNG image, from 1 to 6 (or -1 for the default
|
||
compression level of libpng). This method returns <b>nil</b> on
|
||
error. </p>
|
||
|
||
|
||
<h4>gdImage:jpegStr(quality)</h4>
|
||
|
||
<p> This method returns the image in the JPEG format as a Lua string
|
||
or <b>nil</b> on error (eg. a corrupted image). You must specify the
|
||
quality of the generated JPEG data from 1 (worst quality, small string)
|
||
to 100 (best quality, large string). </p>
|
||
|
||
<p> Example: </p>
|
||
<pre class="example">
|
||
-- creates a new image
|
||
local im = gd.createTrueColor(20, 20)
|
||
|
||
-- ** DO SOME ART HERE **
|
||
-- writes the image to a PNG file.
|
||
im:png("picture.png")
|
||
|
||
-- writes the image to stdout in the JPEG format
|
||
io.write(im:jpegStr(75))
|
||
</pre>
|
||
|
||
|
||
|
||
<h4>gdImage:gifStr()</h4>
|
||
|
||
<p> This method returns the image in the GIF format as a Lua string
|
||
or <b>nil</b> on error (eg. a corrupted image).</p>
|
||
|
||
|
||
<h4>gdImage:gdStr()</h4>
|
||
|
||
<p> This method returns the image in the gd format as a Lua string
|
||
or <b>nil</b> on error (eg. a corrupted image).</p>
|
||
|
||
|
||
<h4>gdImage:gd2Str(chunkSize, format)</h4>
|
||
|
||
<p> This method returns the image in the gd2 format as a Lua string or
|
||
<b>nil</b> on error (eg. a corrupted image). You must specify the chunk
|
||
size (an integer, or 0 for the default) and the data format, which can be
|
||
<code>gd.GD2_FMT_RAW</code> or <code>gd.GD2_FMT_COMPRESSED</code>. This
|
||
format is not intended for general purpose use and should never be used
|
||
to distribute images. Its purpose is solely to allow very fast loading
|
||
of images. </p>
|
||
|
||
|
||
<h4>gdImage:wbmpStr(fg)</h4>
|
||
|
||
<p> This method returns the image in the WBMP format as a Lua string
|
||
or <b>nil</b> on error (eg. a corrupted image). WBMP format support is
|
||
black and white only. The color index specified by the fg argument is
|
||
the "foreground", and only pixels of this color will be set in the WBMP
|
||
string. All other pixels will be considered "background". </p>
|
||
|
||
|
||
|
||
<a name="api.color"></a>
|
||
<h3>Color manipulation methods</h3>
|
||
|
||
|
||
<h4>gdImage:colorAllocate(red, green, blue)</h4>
|
||
|
||
<p><code>colorAllocate()</code> finds the first available color
|
||
index in the image specified, sets its RGB values to those requested
|
||
(255 is the maximum for each), and returns the index of the new color
|
||
table entry, or an RGBA value in the case of a truecolor image; in
|
||
either case you can then use the returned value as a parameter to
|
||
drawing methods. When creating a new palette-based image, the first
|
||
time you invoke this method, you are setting the background color for
|
||
that image.</p>
|
||
|
||
<p>In the event that all <code>gd.MAX_COLORS</code> colors (256)
|
||
have already been allocated, <code>colorAllocate</code> will
|
||
return <b>nil</b> to indicate failure. (This is not uncommon when working
|
||
with existing PNG files that already use 256 colors). Note that
|
||
<code>colorAllocate</code> does not check for existing colors that match
|
||
your request; see <code>colorExact</code>, <code>colorClosest</code>
|
||
and <code>colorClosestHWB</code> for ways to locate existing colors
|
||
that approximate the color desired in situations where a new color is
|
||
not available.</p>
|
||
|
||
|
||
<h4>gdImage:colorAllocateAlpha(red, green, blue, alpha)</h4>
|
||
|
||
<p><code>colorAllocateAlpha</code> finds the first available color index
|
||
in the image specified, sets its RGBA values to those requested (255 is
|
||
the maximum for red, green and blue, and 127 represents full transparency
|
||
for alpha), and returns the index of the new color table entry, or an RGBA
|
||
value in the case of a truecolor image; in either case you can then use
|
||
the returned value as a parameter to drawing methods. When creating
|
||
a new palette-based image, the first time you invoke this method,
|
||
you are setting the background color for that image.</p>
|
||
|
||
<p>In the event that all <code>gd.MAX_COLORS</code> colors (256) have
|
||
already been allocated, <code>colorAllocateAlpha</code> will return
|
||
<b>nil</b> to indicate failure. (This is not uncommon when working with
|
||
existing palette-based PNG files that already use 256 colors). Note
|
||
that <code>colorAllocateAlpha</code> does not check for existing
|
||
colors that match your request; see <code>colorExactAlpha</code> and
|
||
<code>colorClosestAlpha</code> for ways to locate existing colors that
|
||
approximate the color desired in situations where a new color is not
|
||
available. Also see <code>colorResolveAlpha</code>.</p>
|
||
|
||
|
||
|
||
<h4>gdImage:colorClosest(red, green, blue)</h4>
|
||
|
||
<p><code>colorClosest</code> searches the colors which have been defined
|
||
thus far in the image specified and returns the index of the color with
|
||
RGB values closest to those of the request. (Closeness is determined
|
||
by Euclidian distance, which is used to determine the distance in
|
||
three-dimensional color space between colors). </p>
|
||
|
||
<p>If no colors have yet been allocated in the image,
|
||
<code>colorClosest</code> returns <b>nil</b>.</p>
|
||
|
||
<p>When applied to a truecolor image, this method always succeeds in
|
||
returning the desired color.</p>
|
||
|
||
<p>This method is most useful as a backup method for choosing a
|
||
drawing color when an image already contains <code>gd.MAX_COLORS</code>
|
||
(256) colors and no more can be allocated. (This is not uncommon when
|
||
working with existing PNG files that already use many colors). See
|
||
<code>colorExact</code> for a method of locating exact matches only.</p>
|
||
|
||
|
||
<h4>gdImage:colorClosestAlpha(red, green, blue, alpha)</h4>
|
||
|
||
<p> <code>colorClosestAlpha</code> searches the colors which have been
|
||
defined thus far in the image specified and returns the index of the
|
||
color with RGBA values closest to those of the request. (Closeness is
|
||
determined by Euclidian distance, which is used to determine the distance
|
||
in four-dimensional color/alpha space between colors). </p>
|
||
|
||
<p> If no colors have yet been allocated in the image,
|
||
<code>colorClosestAlpha</code> returns <b>nil</b>. </p>
|
||
|
||
<p> When applied to a truecolor image, this method always succeeds in
|
||
returning the desired color. </p>
|
||
|
||
<p> This method is most useful as a backup method for
|
||
choosing a drawing color when a palette-based image already
|
||
contains <code>gd.MAX_COLORS</code> (256) colors and no more can be
|
||
allocated. (This is not uncommon when working with existing palette-based
|
||
PNG files that already use many colors). See <code>colorExactAlpha</code>
|
||
for a method of locating exact matches only.</p>
|
||
|
||
|
||
<h4>gdImage:colorClosestHWB(red, green, blue)</h4>
|
||
|
||
<p> <code>colorClosestHWB</code> searches the colors which have been
|
||
defined thus far in the image specified and returns the index of the color
|
||
with hue, whiteness and blackness closest to the requested color. This
|
||
scheme is typically superior to the Euclidian distance scheme used by
|
||
<code>colorClosest</code>. </p>
|
||
|
||
<p> If no colors have yet been allocated in the image,
|
||
<code>colorClosestHWB</code> returns <b>nil</b>. </p>
|
||
|
||
<p> When applied to a truecolor image, this method always succeeds in
|
||
returning the desired color. </p>
|
||
|
||
<p> This method is most useful as a backup method for choosing a
|
||
drawing color when an image already contains <code>gd.MAX_COLORS</code>
|
||
(256) colors and no more can be allocated. (This is not uncommon when
|
||
working with existing PNG files that already use many colors). See
|
||
<code>colorExact</code> for a method of locating exact matches only. </p>
|
||
|
||
|
||
<h4>gdImage:colorExact(red, green, blue)</h4>
|
||
|
||
<p> <code>colorExact</code> searches the colors which have been defined
|
||
thus far in the image specified and returns the index of the first
|
||
color with RGB values which exactly match those of the request. If no
|
||
allocated color matches the request precisely, <code>colorExact</code>
|
||
returns <b>nil</b>. See <code>colorClosest</code> for a way to find the
|
||
color closest to the color requested.</p>
|
||
|
||
<p> When applied to a truecolor image, this method always succeeds in
|
||
returning the desired color. </p>
|
||
|
||
|
||
<h4>gdImage:colorExactAlpha(red, green, blue, alpha)</h4>
|
||
|
||
<p> <code>colorExactAlpha</code> searches the colors which have
|
||
been defined thus far in the image specified and returns the
|
||
index of the first color with RGBA values which exactly match
|
||
those of the request. If no allocated color matches the request
|
||
precisely, <code>colorExactAlpha</code> returns <b>nil</b>. See
|
||
<code>colorClosestAlpha</code> for a way to find the color closest to
|
||
the color requested.</p>
|
||
|
||
<p> When applied to a truecolor image, this method always succeeds in
|
||
returning the desired color. </p>
|
||
|
||
<h4>gdImage:colorResolve(red, green, blue)</h4>
|
||
|
||
<p> <code>colorResolve</code> searches the colors which have been defined
|
||
thus far in the image specified and returns the index of the first color
|
||
with RGB values which exactly match those of the request. If no allocated
|
||
color matches the request precisely, then <code>colorResolve</code>
|
||
tries to allocate the exact color. If there is no space left in
|
||
the color table then ColorResolve returns the closest color (as in
|
||
<code>colorClosest</code>). This method always returns an index of a
|
||
color. </p>
|
||
|
||
<p> When applied to a truecolor image, this method always succeeds in
|
||
returning the desired color. </p>
|
||
|
||
|
||
<h4>gdImage:colorResolveAlpha(red, green, blue, alpha)</h4>
|
||
|
||
<p> <code>colorResolveAlpha</code> searches the colors which have
|
||
been defined thus far in the image specified and returns the index
|
||
of the first color with RGBA values which exactly match those of the
|
||
request. If no allocated color matches the request precisely, then
|
||
<code>colorResolveAlpha</code> tries to allocate the exact color. If there
|
||
is no space left in the color table then <code>colorResolveAlpha</code>
|
||
returns the closest color (as in <code>colorClosestAlpha</code>). This
|
||
method always returns an index of a color. </p>
|
||
|
||
<p> When applied to a truecolor image, this method always succeeds in
|
||
returning the desired color. </p>
|
||
|
||
|
||
<h4>gdImage:colorsTotal()</h4>
|
||
<p> This method returns the number of colors currently allocated in a
|
||
palette image. For truecolor images, the result of this call is undefined
|
||
and should not be used. </p>
|
||
|
||
|
||
<h4>gdImage:red(color)</h4>
|
||
<p> This method returns the red portion of the specified color in the
|
||
image. This method works for both palette and truecolor images. </p>
|
||
|
||
|
||
<h4>gdImage:blue(color)</h4>
|
||
<p> This method returns the blue portion of the specified color in the
|
||
image. This method works for both palette and truecolor images. </p>
|
||
|
||
|
||
<h4>gdImage:green(color)</h4>
|
||
<p> This method returns the green portion of the specified color in the
|
||
image. This method works for both palette and truecolor images. </p>
|
||
|
||
|
||
<h4>gdImage:alpha(color)</h4>
|
||
|
||
<p> This method returns the alpha portion of the specified color in the
|
||
image. This method works for both palette and truecolor images. </p>
|
||
|
||
|
||
<h4>gdImage:getTransparent()</h4>
|
||
<p> This method returns the current transparent color index in
|
||
the image. If there is no transparent color, <code>getTransparent</code>
|
||
returns <b>nil</b>. </p>
|
||
|
||
|
||
<h4>gdImage:colorTransparent(color)</h4>
|
||
|
||
<p><code>colorTransparent</code> sets the transparent color index for
|
||
the specified image to the specified index. To indicate that there
|
||
should be no transparent color, invoke <code>colorTransparent</code>
|
||
with a color index of <b>nil</b> (or passing no color index). Note that
|
||
JPEG images do not support transparency, so this setting has no effect
|
||
when writing JPEG images.</p>
|
||
|
||
<p>The color index used should be an index allocated by
|
||
<code>colorAllocate</code>, whether explicitly invoked by your code or
|
||
implicitly invoked by loading an image. In order to ensure that your
|
||
image has a reasonable appearance when viewed by users who do not
|
||
have transparent background capabilities (or when you are writing a
|
||
JPEG-format file, which does not support transparency), be sure to give
|
||
reasonable RGB values to the color you allocate for use as a transparent
|
||
color, even though it will be transparent on systems that support PNG
|
||
transparency.</p>
|
||
|
||
|
||
<h4>gdImage:colorDeallocate(color)</h4>
|
||
|
||
<p> <code>colorDeallocate</code> marks the specified color as being
|
||
available for reuse. It does not attempt to determine whether the
|
||
color index is still in use in the image. After a call to this
|
||
method, the next call to <code>colorAllocate</code> for the same
|
||
image will set new RGB values for that color index, changing the color
|
||
of any pixels which have that index as a result. If multiple calls to
|
||
<code>colorDeallocate</code> are made consecutively, the lowest-numbered
|
||
index among them will be reused by the next <code>colorAllocate</code>
|
||
call.<p>
|
||
|
||
|
||
<a name="api.query"></a>
|
||
<h3>Query methods</h3>
|
||
|
||
<h4>gdImage:boundsSafe(x, y)</h4>
|
||
|
||
<p> <code>boundsSafe</code> returns <b>true</b> if the specified point
|
||
is within the current clipping rectangle, <b>false</b> if not. The
|
||
clipping rectangle is set by <code>setClip</code> and defaults to the
|
||
entire image. This method is intended primarily for use by those who
|
||
wish to add methods to Lua-GD. All of the drawing functions already
|
||
clip safely. </p>
|
||
|
||
|
||
<h4>gdImage:getPixel(x, y)</h4>
|
||
<p><code>getPixel</code> returns the color index of a particular pixel.</p>
|
||
|
||
<h4>gdImage:sizeX()</h4>
|
||
<p><code>sizeX</code> returns the width of the image in pixels.</p>
|
||
|
||
|
||
<h4>gdImage:sizeY()</h4>
|
||
<p><code>sizeY</code> returns the height of the image in pixels.</p>
|
||
|
||
|
||
<h4>gdImage:sizeXY()</h4>
|
||
<p><code>sizeXY</code> returns the width and the height of the image
|
||
in pixels. This method has no C equivalent because, unlike Lua,
|
||
C functions cannot return multiple values.</p>
|
||
|
||
<p>Example: </p>
|
||
<pre class="example">
|
||
local x, y = im:sizeXY()
|
||
</pre>
|
||
|
||
|
||
|
||
<h4>gdImage:getClip()</h4>
|
||
<p>Fetches the boundaries of the current clipping rectangle. This method
|
||
returns four numbers.</p>
|
||
|
||
<p>Example: </p>
|
||
<pre class="example">
|
||
local x1, y1, x2, y2 = im:getClip()
|
||
</pre>
|
||
|
||
|
||
|
||
<h4>gdImage:setClip(x1, y1, x2, y2)</h4>
|
||
|
||
<p> Establishes a clipping rectangle. Once <code>setClip</code> has been
|
||
called, all future drawing operations will remain within the specified
|
||
clipping area, until a new <code>setClip</code> call takes place. For
|
||
instance, if a clipping rectangle of 25, 25, 75, 75 has been set within
|
||
a 100x100 image, a diagonal line from 0,0 to 99,99 will appear only
|
||
between 25,25 and 75,75. </p>
|
||
|
||
|
||
<a name="api.draw"></a>
|
||
<h3>Drawing methods</h3>
|
||
|
||
<h4>gdImage:setPixel(x, y, color)</h4>
|
||
<p> <code>setPixel</code> sets a pixel to a particular color index. </p>
|
||
|
||
<h4>gdImage:line(x1, y1, x2, y2, color)</h4>
|
||
|
||
<p> <code>line</code> is used to draw a line between two endpoints
|
||
(x1,y1 and x2, y2). The line is drawn using the color index
|
||
specified. Note that the color index can be an actual color returned
|
||
by <code>colorAllocate</code> or one of <code>gd.STYLED</code>,
|
||
<code>gd.BRUSHED</code> or <code>gd.STYLED_BRUSHED</code>. </p>
|
||
|
||
|
||
<h4>gdImage:rectangle(x1, y1, x2, y2, color)</h4>
|
||
|
||
<p> <code>rectangle</code> is used to draw a rectangle with the two
|
||
corners (upper left first, then lower right) specified, using the color
|
||
index specified. </p>
|
||
|
||
|
||
<h4>gdImage:filledRectangle(x1, y1, x2, y2, color)</h4>
|
||
|
||
<p> <code>filledRectangle</code> is used to draw a rectangle with the
|
||
two corners (upper left first, then lower right) specified, filled using
|
||
the color index specified. </p>
|
||
|
||
|
||
<h4>gdImage:polygon({ { x1, y1 }, { x2, y2 } ... }, color)</h4>
|
||
|
||
<p> <code>polygon</code> is used to draw a polygon with the verticies
|
||
(at least 3) specified in the table, using the color index specified. </p>
|
||
|
||
<p>Example: </p>
|
||
<pre class="example">
|
||
im = assert(gd.createTrueColor(80, 80))
|
||
black = im:colorAllocate(0, 0, 0)
|
||
white = im:colorAllocate(255, 255, 255)
|
||
im:polygon( { { 10, 10 }, { 10, 20 }, { 20, 20 }, { 20, 10 } }, white)
|
||
im:png("out.png")
|
||
</pre>
|
||
|
||
|
||
|
||
|
||
<h4>gdImage:filledPolygon({ { x1, y1 }, { x2, y2 } ... }, color)</h4>
|
||
|
||
<p> <code>polygon</code> is used to fill a polygon with the verticies
|
||
(at least 3) specified in the table, using the color index specified. </p>
|
||
|
||
<p>Example: </p>
|
||
<pre class="example">
|
||
im = assert(gd.createTrueColor(80, 80))
|
||
black = im:colorAllocate(0, 0, 0)
|
||
white = im:colorAllocate(255, 255, 255)
|
||
im:filledPolygon( { { 30, 30 }, { 30, 40 }, { 40, 40 }, { 40, 30 } }, white)
|
||
im:png("out.png")
|
||
</pre>
|
||
|
||
|
||
|
||
|
||
|
||
<h4>gdImage:openPolygon({ { x1, y1 }, { x2, y2 } ... }, color)</h4>
|
||
|
||
<p> <code>openPolygon</code> is used to draw a sequence of lines with the
|
||
verticies (at least 3) specified, using the color index specified. Unlike
|
||
<code>polygon</code>, the enpoints of the line sequence are not connected to
|
||
a closed polygon. </p>
|
||
|
||
<p>Example: </p>
|
||
<pre class="example">
|
||
im = assert(gd.createTrueColor(80, 80))
|
||
black = im:colorAllocate(0, 0, 0)
|
||
white = im:colorAllocate(255, 255, 255)
|
||
im:openPolygon( { { 50, 50 }, { 50, 60 }, { 60, 60 }, { 60, 50 } }, white)
|
||
im:png("out.png")
|
||
</pre>
|
||
|
||
|
||
|
||
|
||
<h4>gdImage:arc(cx, cy, w, h, s, e, color)</h4>
|
||
|
||
<p> <code>arc</code> is used to draw a partial ellipse centered at the
|
||
given point, with the specified width and height in pixels. The arc
|
||
begins at the position in degrees specified by <b>s</b> and ends at the
|
||
position specified by <b>e</b>. The arc is drawn in the color specified
|
||
by the last argument. A circle can be drawn by beginning from 0 degrees
|
||
and ending at 360 degrees, with width and height being equal. <b>e</b>
|
||
must be greater than <b>s</b>. Values greater than 360 are interpreted
|
||
modulo 360. </p>
|
||
|
||
|
||
<h4>gdImage:filledArc(cx, cy, w, h, s, e, color, style)</h4>
|
||
|
||
<p> <code>filledArc</code> is used to draw a partial ellipse centered at
|
||
the given point, with the specified width and height in pixels. The arc
|
||
begins at the position in degrees specified by <b>s</b> and ends at the
|
||
position specified by <b>e</b>. The arc is filled in the color specified
|
||
by <b>color</b>. A circle can be drawn by beginning from 0 degrees
|
||
and ending at 360 degrees, with width and height being equal. <b>e</b>
|
||
must be greater than <b>s</b>. Values greater than 360 are interpreted
|
||
modulo 360. The last argument is a sum of the following possibilities:
|
||
<code>gd.ARC</code>, <code>gd.CHORD</code>, <code>gd.PIE</code>
|
||
(synonym for <code>gd.CHORD</code>), <code>gd.NO_FILL</code> and
|
||
<code>gd.EDGED</code>. <code>gd.ARC</code> and <code>gd.CHORD</code> are
|
||
mutually exclusive; <code>gd.CHORD</code> just connects the starting
|
||
and ending angles with a straight line, while <code>gd.ARC</code>
|
||
produces a rounded edge. <code>gd.PIE</code> is a synonym for
|
||
<code>gd.ARC</code>. <code>gd.NO_FILL</code> indicates that the arc
|
||
or chord should be outlined, not filled. <code>gd.EDGED</code>, used
|
||
together with <code>gd.NO_FILL</code>, indicates that the beginning and
|
||
ending angles should be connected to the center; this is a good way to
|
||
outline (rather than fill) a 'pie slice'. </p>
|
||
|
||
|
||
<h4>gdImage:filledEllipse(cx, cy, w, h, color)</h4>
|
||
|
||
<p> <code>filledEllipse</code> is used to draw an ellipse centered at the
|
||
given point, with the specified width and height in pixels. The ellipse
|
||
is filled in the color specified by the last argument.</p>
|
||
|
||
|
||
<h4>gdImage:fill(x, y, c)</h4>
|
||
|
||
<p> <code>fill</code> floods a portion of the image with the specified
|
||
color, beginning at the specified point and flooding the surrounding
|
||
region of the same color as the starting point. For a way of flooding
|
||
a region defined by a specific border color rather than by its interior
|
||
color, see <code>fillToBorder</code>. </p>
|
||
|
||
<p>The fill color can be <code>gd.TILED</code>, resulting in a tile
|
||
fill using another image as the tile. However, the tile image cannot be
|
||
transparent. If the image you wish to fill with has a transparent color
|
||
index, call <code>setTransparent</code> on the tile image and set the
|
||
transparent color index to <b>nil</b> to turn off its transparency. </p>
|
||
|
||
<h4>gdImage:fillToBorder(x, y, border_color, color)</h4>
|
||
|
||
<p> <code>fillToBorder</code> floods a portion of the image with the
|
||
specified color, beginning at the specified point and stopping at the
|
||
specified border color. For a way of flooding an area defined by the
|
||
color of the starting point, see <code>fill</code>. </p>
|
||
|
||
<p> The border color cannot be a special color such as
|
||
<code>gd.TILED</code>; it must be a proper solid color. The fill color
|
||
can be, however. </p>
|
||
|
||
|
||
<a name="api.text"></a>
|
||
<h3>Text drawing methods</h3>
|
||
|
||
<h4>gdImage:string(font, x, y, string, color)</h4>
|
||
|
||
<p> This method draws the string in the fourth argument on the image
|
||
using one of the standard gd fonts (<code>gd.FONT_TINY</code>,
|
||
<code>gd.FONT_SMALL</code>, <code>gd.FONT_MEDIUM</code>,
|
||
<code>gd.FONT_LARGE</code> or <code>gd.FONT_GIANT</code>) from left
|
||
to right, starting from the (x, y) point and with the color specified
|
||
by the fifth argument. The string must have only ISO-8859-1 characters
|
||
(you should use <code>gd.stringFT</code> and True Type fonts for drawing
|
||
Unicode strings. </p>
|
||
|
||
<p> Example: </p>
|
||
<pre class="example">
|
||
im = gd.create(140, 80)
|
||
white = im:colorAllocate(255, 255, 255)
|
||
black = im:colorAllocate(0, 0, 0)
|
||
im:string(gd.FONT_TINY, 10, 20, "TINY", black)
|
||
im:string(gd.FONT_SMALL, 10, 30, "SMALL", black)
|
||
im:string(gd.FONT_MEDIUM, 10, 45, "MEDIUM", black)
|
||
im:string(gd.FONT_LARGE, 10, 58, "LARGE", black)
|
||
im:string(gd.FONT_GIANT, 10, 75, "GIANT", black)
|
||
im:png("out.png")
|
||
</pre>
|
||
|
||
|
||
<h4>gdImage:stringUp(fontname, x, y, string, color)</h4>
|
||
|
||
<p> Similar to <code>gd.string</code> but the string will be drawn
|
||
vertically (rotated 90 degrees), from bottom to up, starting from the
|
||
(x, y) point. The string must have only ISO-8859-1 characters. If you
|
||
want use Unicode characters or other rotations than 90<39>, you should
|
||
use <code>gd.stringFT</code> and True Type fonts. </p>
|
||
|
||
<h4>gdImage:stringFT(color, fontname, ptsize, angle, x, y, string)</h4>
|
||
|
||
<p> <code>stringFT</code> draws a string of anti-aliased characters on the
|
||
image using the FreeType library to render user-supplied TrueType fonts.
|
||
The string is anti-aliased, meaning that there should be fewer "jaggies"
|
||
visible. The fontname is the full pathname to a TrueType font file,
|
||
or a font face name if the <code>GDFONTPATH</code> environment variable
|
||
have been set intelligently. In the absence of a full path, the font face
|
||
name may be presented with or without extension. Font names can also be
|
||
<a href="http://fontconfig.org/fontconfig-user.html#AEN36">fontconfig
|
||
patterns</a> (see <code>gd.useFontConfig</code>) so, the library will
|
||
automatically use fonts from your operating system.</p>
|
||
|
||
<p> The string argument is considered to be encoded via the UTF-8
|
||
standard; also, HTML entities are supported, including decimal,
|
||
hexadecimal, and named entities. Those who are passing ordinary
|
||
ASCII strings may have difficulty with the & character unless
|
||
encoded correctly as <code>&amp;</code> but should have no other
|
||
difficulties.</p>
|
||
|
||
<p> The string may be arbitrarily scaled (ptsize) and rotated (angle in
|
||
radians). The direction of rotation is counter-clockwise, with 0 radians
|
||
(0 degrees) at 3 o'clock and PI/2 radians (90 degrees) at 12 o'clock
|
||
(you should use <code>math.rad</code> to convert degrees to radians).
|
||
The string is rendered in the color indicated by the color index. Use
|
||
the negative of the desired color index to disable anti-aliasing. </p>
|
||
|
||
<p> This method return eight values with the limits of the rendered
|
||
text on sucess or <b>nil</b> on failure. The following code show how to
|
||
use them to draw a bounding rectangle arround the text. </p>
|
||
|
||
<pre class="example">
|
||
im = gd.createTrueColor(100, 100)
|
||
black = im:colorAllocate(0, 0, 0)
|
||
white = im:colorAllocate(255, 255, 255)
|
||
blue = im:colorAllocate(0, 0, 240)
|
||
im:filledRectangle(0, 0, 100, 100, black)
|
||
llx, lly, lrx, lry, urx, ury, ulx, uly = im:stringFT(white, "Vera.ttf", 20, math.rad(45), 20, 90, "Lua-GD")
|
||
im:polygon({ {llx, lly}, {lrx, lry}, {urx, ury}, {ulx, uly} }, blue)
|
||
</pre>
|
||
|
||
<p> Variables used above can be translated as follows. The points are relative
|
||
to the text regardless of the angle, so "upper left" means in the top
|
||
left-hand corner seeing the text horizontally. </p>
|
||
|
||
<table>
|
||
<tr>
|
||
<td class="h"> # </td>
|
||
<td class="h"> Name </td>
|
||
<td class="h"> Meaning </td>
|
||
</tr>
|
||
<tr>
|
||
<td> 1 </td>
|
||
<td class="n"> llx </td>
|
||
<td> lower left corner, X position </td>
|
||
</tr>
|
||
<tr>
|
||
<td> 2 </td>
|
||
<td class="n"> lly </td>
|
||
<td> lower left corner, Y position </td>
|
||
</tr>
|
||
<tr>
|
||
<td> 3 </td>
|
||
<td class="n"> lrx </td>
|
||
<td> lower right corner, X position </td>
|
||
</tr>
|
||
<tr>
|
||
<td> 4 </td>
|
||
<td class="n"> lry </td>
|
||
<td> lower right corner, Y position </td>
|
||
</tr>
|
||
<tr>
|
||
<td> 5 </td>
|
||
<td class="n"> urx </td>
|
||
<td> upper right corner, X position </td>
|
||
</tr>
|
||
<tr>
|
||
<td> 6 </td>
|
||
<td class="n"> ury </td>
|
||
<td> upper right corner, Y position </td>
|
||
</tr>
|
||
<tr>
|
||
<td> 7 </td>
|
||
<td class="n"> ulx </td>
|
||
<td> upper left corner, X position </td>
|
||
</tr>
|
||
<tr>
|
||
<td> 8 </td>
|
||
<td class="n"> uly </td>
|
||
<td> upper left corner, Y position </td>
|
||
</tr>
|
||
</table>
|
||
|
||
<p> Also, there is a way to get these values before drawing on the image
|
||
passing <b>nil</b> as the first argument of <code>gd.stringFT</code> (note
|
||
the absence of the colon notation!), as follows. This is a relatively
|
||
cheap operation if followed by a rendering of the same string, because
|
||
of the caching of the partial rendering during bounding rectangle
|
||
calculation. </p>
|
||
|
||
<pre class="example">
|
||
llx, lly, lrx, lry, urx, ury, ulx, uly = gd.stringFT(nil, white, "Vera.ttf", 20, math.rad(45), 20, 90, "Lua-GD")
|
||
</pre>
|
||
|
||
|
||
|
||
<h4>gdImage:stringFTEx(color, fontname, ptsize, angle, x, y, string, extra)</h4>
|
||
|
||
<p> This is an extended version of <code>stringFT</code> that accepts
|
||
a table as an <b>extra</b> argument, which allows you to pass some
|
||
parameters to the rendering engine. The fields currently available are
|
||
show bellow: </p>
|
||
|
||
<table>
|
||
<tr>
|
||
<td class="h"> Field name </td>
|
||
<td class="h"> Type </td>
|
||
<td class="h"> Default </td>
|
||
<td class="h"> Usage </td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td class="n"> linespacing </td>
|
||
<td class="i"> float </td>
|
||
<td class="i"> 1.05 </td>
|
||
<td> Allows you to set the space between lines when rendering multiple
|
||
lines. A line spacing of 1.0 is the minimum to guarantee that lines
|
||
of text do not collide.</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td class="n"> charmap </td>
|
||
<td class="i"> indexed </td>
|
||
<td class="i"> gd.FTEX_Unicode </td>
|
||
<td> Allows you to set a specific character encoding schema, which can
|
||
be any of <code>gd.FTEX_Unicode</code>,
|
||
<code>gd.FTEX_Shift_JIS</code>, or <code>gd.FTEX_Big5</code>. It is
|
||
useful when a font offers more than one of Unicode, Shift_JIS, and
|
||
Big5. If you do not specify one, Unicode will be tried first. If
|
||
the preferred character mapping is not found in the font, other
|
||
character mappings are attempted.</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td class="n"> hdpi </td>
|
||
<td class="i"> integer </td>
|
||
<td class="i"> 96 </td>
|
||
<td> Sets the horizontal resolution passed to the FreeType engine. </td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td class="n"> vdpi </td>
|
||
<td class="i"> integer </td>
|
||
<td class="i"> 96 </td>
|
||
<td> Sets the vertical resolution passed to the FreeType engine. </td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td class="n"> disable_kerning </td>
|
||
<td class="i"> boolean </td>
|
||
<td class="i"> false </td>
|
||
<td> If fontconfig is available, gd will normally attempt to apply
|
||
kerning tables to adjust the relative positions of consecutive
|
||
characters more ideally for that pair of characters. This field
|
||
allows you to turn this feature off. </td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td class="n"> xshow </td>
|
||
<td class="i"> boolean</td>
|
||
<td class="i"> false </td>
|
||
<td> Request gd to return a vector of individual character position
|
||
advances, occasionally useful in applications that must know exactly
|
||
where each character begins. This is returned as a string with values
|
||
separated by spaces. </td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td class="n"> return_font_path_name </td>
|
||
<td class="i"> boolean </td>
|
||
<td class="i"> false </td>
|
||
<td> Returns the path to the font used to render the text. This is
|
||
useful because gd are capable of selecting a font automatically
|
||
based on a fontconfig font pattern when fontconfig is available. </td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td class="n"> fontconfig </td>
|
||
<td class="i"> boolean </td>
|
||
<td class="i"> false </td>
|
||
<td> gd can use fontconfig to resolve font names, including fontconfig
|
||
patterns, if this field is set to <b>true</b>. As a convenience,
|
||
this behavior can also be made the default by calling
|
||
<code>gd.useFontConfig</code> with a <b>true</b> value. </td>
|
||
</tr>
|
||
|
||
</table>
|
||
|
||
<p> This method also returns the same values than <code>stringFT</code>,
|
||
more two aditional ones if the fields <b>xshow</b> or
|
||
<b>return_font_path_name</b> are set to <b>true</b>. See the following
|
||
example: </p>
|
||
|
||
<pre class="example">
|
||
llX, llY, lrX, lrY, urX, urY, ulX, ulY =
|
||
im:stringFTEx(blue, "Vera", 20, 0, 50, 50, "Lua-GD",
|
||
{ hdpi = 40, vdpi = 20 } )
|
||
|
||
llX, llY, lrX, lrY, urX, urY, ulX, ulY, pos =
|
||
im:stringFTEx(blue, "Vera", 20, 0, 50, 150, "Lua-GD",
|
||
{ hdpi = 40, vdpi = 20, xshow = true } )
|
||
|
||
llX, llY, lrX, lrY, urX, urY, ulX, ulY, fontpath =
|
||
im:stringFTEx(blue, "Vera", 20, 0, 50, 250, "Lua-GD",
|
||
{ hdpi = 40, vdpi = 20, return_font_path_name = true } )
|
||
|
||
llX, llY, lrX, lrY, urX, urY, ulX, ulY, pos, fontpath =
|
||
im:stringFTEx(blue, "Vera", 20, 0, 50, 350, "Lua-GD",
|
||
{ hdpi = 40, vdpi = 20, xshow = true, return_font_path_name = true } )
|
||
</pre>
|
||
|
||
|
||
|
||
|
||
<h4>gdImage:stringFTCircle(cx, cy, radius, textRadius, fillPortion, fontname, points, top, bottom, color)</h4>
|
||
|
||
<p> Draws the text strings specified by <b>top</b> and <b>bottom</b> on
|
||
the image, curved along the edge of a circle of radius <b>radius</b>,
|
||
with its center at <b>cx</b> and <b>cy</b>. <b>top</b> is written
|
||
clockwise along the top; <b>bottom</b> is written counterclockwise along
|
||
the bottom. <b>textRadius</b> determines the "height" of each character;
|
||
if <b>textRadius</b> is 1/2 of <b>radius</b>, characters extend halfway
|
||
from the edge to the center. <b>fillPortion</b> varies from 0 to 1.0,
|
||
with useful values from about 0.4 to 0.9, and determines how much of the
|
||
180 degrees of arc assigned to each section of text is actually occupied
|
||
by text; 0.9 looks better than 1.0 which is rather crowded. <b>fontname</b>
|
||
is a freetype font; see <code>gd.stringFT</code>. <b>points</b> is
|
||
passed to the freetype engine and has an effect on hinting; although
|
||
the size of the text is determined by <b>radius</b>, <b>textRadius</b>,
|
||
and <b>fillPortion</b>, you should pass a point size that "hints"
|
||
appropriately -- if you know the text will be large, pass a large point
|
||
size such as 24.0 to get the best results. <b>color</b> can be any color,
|
||
and may have an alpha component, do blending, etc. </p>
|
||
|
||
|
||
<a name="api.font"></a>
|
||
<h3>Font configuration methods</h3>
|
||
|
||
<h4>gd.useFontConfig(bool)</h4>
|
||
<p> gd has the ability to use
|
||
<a href="http://fontconfig.org/fontconfig-user.html#AEN36">fontconfig
|
||
patterns</a> rather than font file names as parameters to
|
||
<code>gd.stringFT</code> and <code>gd.stringFTCircle</code>. For
|
||
backwards compatibility reasons, the fontlist parameter to those
|
||
functions is still expected to be a full or partial font file path
|
||
name or list thereof by default. However, as a convenience, a single
|
||
call to <code>gd.useFontConfig</code> with a <b>true</b> parameter
|
||
configures Lua-GD to expect the fontlist parameter to be a fontconfig
|
||
pattern. Otherwise, calling <code>gd.useFontConfig</code> with a
|
||
<b>false</b> parameter will disable the fontconfig patters. </p>
|
||
|
||
|
||
<h4>gd.fontCacheSetup()</h4>
|
||
|
||
<p> This function initializes the font cache for freetype text
|
||
output functions such as <code>gd.stringFT</code>. If this function
|
||
is not called by the programmer, it is invoked automatically on the
|
||
first truetype text output call, which is perfectly safe unless the
|
||
application is multithreaded (either using LuaThreads or running Lua from
|
||
a different thread in your host program which also uses gd from the C API)
|
||
. Multithreaded applications should directly invoke this function before
|
||
allowing any thread to use freetype text output. You don't need to call
|
||
this functions if you are using Lua coroutines because any calls from
|
||
Lua to C API ara atomic. This function returns <b>true</b> on success
|
||
or <b>false</b> if the freetype library fails to initialize. </p>
|
||
|
||
|
||
<h4>gd.fontCacheShutdown()</h4>
|
||
|
||
<p> This function releases the memory used by the freetype font cache
|
||
and the text output mutex. Applications that use Lua-GD for their entire
|
||
lifetime, then exit, need not call this function. This function has no
|
||
return value. </p>
|
||
|
||
|
||
|
||
<a name="api.copy"></a>
|
||
<h3>Image copying, resizing and transformation methods</h3>
|
||
|
||
|
||
<h4>gd.copy(dstImage, srcImage, dstX, dstY, srcX, srcY, w, h) <br>
|
||
dstImage:copy(srcImage, dstX, dstY, srcX, srcY, w, h)</h4>
|
||
|
||
<p> <code>gd.copy</code> is used to copy a rectangular portion of one
|
||
image to another image (For a way of stretching or shrinking the image
|
||
in the process, see <code>gd.copyResized</code>). </p>
|
||
|
||
<p> The <b>dstImage</b> argument is the destination image to which
|
||
the region will be copied (you can use the colon notation for it). The
|
||
<b>srcImage</b> argument is the source image from which the region is
|
||
copied. The <b>dstX</b> and <b>dstY</b> arguments specify the point in
|
||
the destination image to which the region will be copied. The <b>srcX</b>
|
||
and <b>srcY</b> arguments specify the upper left corner of the region
|
||
in the source image. The <b>w</b> and <b>h</b> arguments specify the
|
||
width and height of the region. </p>
|
||
|
||
<p> When you copy a region from one location in an image to another
|
||
location in the same image, <code>gd.copy</code> will perform as
|
||
expected unless the regions overlap, in which case the result is
|
||
<b>unpredictable</b>. </p>
|
||
|
||
<p> <b>Important note on copying between images:</b> since different
|
||
images do not necessarily have the same color tables, pixels are
|
||
not simply set to the same color index values to copy them. If the
|
||
destination image is a palette image, this method will use the
|
||
<code>gd.colorResolve</code> method to determine the best color
|
||
available. </p>
|
||
|
||
|
||
|
||
<h4>gd.copyResized(dstImage, srcImage, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH)<br>
|
||
dstImage:copyResized(srcImage, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH)</h4>
|
||
|
||
|
||
<p> <code>gd.copyResized</code> is used to copy a rectangular portion of
|
||
one image to another image. The X and Y dimensions of the original region
|
||
and the destination region can vary, resulting in stretching or shrinking
|
||
of the region as appropriate (For a simpler version of this method
|
||
which does not deal with resizing, see <code>gd.copy</code>). </p>
|
||
|
||
<p> The <b>dstImage</b> argument is the destination image to which the
|
||
region will be copied. The <code>srcImage</code> argument is the source
|
||
image from which the region is copied. The <b>dstX</b> and <b>dstY</b>
|
||
arguments specify the point in the destination image to which the region
|
||
will be copied. The <b>srcX</b> and <b>srcY</b> arguments specify the
|
||
upper left corner of the region in the source image. The <b>dstW</b>
|
||
and <b>dstH</b> arguments specify the width and height of the destination
|
||
region. The <b>srcW</b> and <b>srcH</b> arguments specify the width and
|
||
height of the source region and can differ from the destination size,
|
||
allowing a region to be scaled during the copying process. </p>
|
||
|
||
<p> When you copy a region from one location in an image to another
|
||
location in the same image, <code>gd.copyResized</code> will perform
|
||
as expected unless the regions overlap, in which case the result is
|
||
<b>unpredictable</b>. </p>
|
||
|
||
<p> <b>Important note on copying between images:</b> since different
|
||
images do not necessarily have the same color tables, pixels are
|
||
not simply set to the same color index values to copy them. If the
|
||
destination image is a palette image, this method will use the
|
||
<code>gd.colorResolve</code> method to determine the best color
|
||
available. </p>
|
||
|
||
|
||
|
||
|
||
<h4>gd.copyResampled(dstImage, srcImage, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH)<br>
|
||
dstImage:copyResampled(srcImage, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH)</h4>
|
||
|
||
<p> <code>gd.copyResampled</code> is used to copy a rectangular portion
|
||
of one image to another image, smoothly interpolating pixel values so
|
||
that, in particular, reducing the size of an image still retains a great
|
||
deal of clarity. The X and Y dimensions of the original region and the
|
||
destination region can vary, resulting in stretching or shrinking of the
|
||
region as appropriate. (For a simpler version of this method which does
|
||
not deal with resizing, see <code>gd.copy</code>. For a version which
|
||
does not interpolate pixel values, see <code>gd.copyResized</code>). </p>
|
||
|
||
<p> Pixel values are only interpolated if the destination image is a
|
||
truecolor image. Otherwise, <code>gd.copyResized</code> is automatically
|
||
invoked.</p>
|
||
|
||
<p> The <b>dstImage</b> argument is the destination image to which
|
||
the region will be copied. The <b>srcImage</b> argument is the source
|
||
image from which the region is copied. The <b>dstX</b> and <b>dstY</b>
|
||
arguments specify the point in the destination image to which the region
|
||
will be copied. The <b>srcX</b> and <b>srcY</b> arguments specify the
|
||
upper left corner of the region in the source image. The <b>dstW</b>
|
||
and <b>dstH</b> arguments specify the width and height of the destination
|
||
region. The <b>srcW</b> and <b>srcH</b> arguments specify the width and
|
||
height of the source region and can differ from the destination size,
|
||
allowing a region to be scaled during the copying process.</p>
|
||
|
||
<p> When you copy a region from one location in an image to another
|
||
location in the same image, <code>gd.copyResampled</code> will perform
|
||
as expected unless the regions overlap, in which case the result is
|
||
<b>unpredictable</b>. If this presents a problem, create a scratch image
|
||
in which to keep intermediate results.</p>
|
||
|
||
<p> <b>Important note on copying between images:</b> since different
|
||
images do not necessarily have the same color tables, pixels are
|
||
not simply set to the same color index values to copy them. If the
|
||
destination image is a palette image, this method will use the
|
||
<code>gd.colorResolve</code> method to determine the best color
|
||
available. </p>
|
||
|
||
|
||
|
||
|
||
<h4>gd.copyRotated(dstImage, srcImage, dstX, dstY, srcX, srcY, srcW, srcH, ang)<br>
|
||
dstImage:copyRotated(srcImage, dstX, dstY, srcX, srcY, srcW, srcH, ang)</h4>
|
||
|
||
<p> <code>gd.copyRotated</code> is used to copy a rectangular portion of
|
||
one image to another image, or to another region of the same image. The
|
||
<b>srcX</b> and <b>srcY</b> coordinates specify the upper left corner of
|
||
the source area; however, the <b>dstX</b> and <b>dstY</b> coordinates
|
||
specify the <b>center</b> of the destination area. This important
|
||
distinction is made because the rotated rectangle may may or may not be
|
||
parallel to the X and Y axes. The destination coordinates may be floating
|
||
point, as the center of the desired destination area may lie at the
|
||
center of a pixel (0.5 pixels) rather than its upper left corner. The
|
||
angle specified is an integer number of degrees, between 0 and 360,
|
||
with 0 degrees causing no change, and counterclockwise rotation as the
|
||
angle increases.</p>
|
||
|
||
<p>When you copy a region from one location in an image to another
|
||
location in the same image, <code>gd.copyRotated</code> will perform
|
||
as expected unless the regions overlap, in which case the result is
|
||
<b>unpredictable</b>. If this presents a problem, create a scratch image
|
||
in which to keep intermediate results.</p>
|
||
|
||
<p> <b>Important note on copying between images:</b> since different
|
||
images do not necessarily have the same color tables, pixels are
|
||
not simply set to the same color index values to copy them. If the
|
||
destination image is a palette image, this method will use the
|
||
<code>gd.colorRotated</code> method to determine the best color
|
||
available. </p>
|
||
|
||
|
||
|
||
<h4>gd.copyMerge(dstImage, srcImage, dstX, dstY, srcX, srcY, w, h, pct)<br>
|
||
dstImage:copyMerge(srcImage, dstX, dstY, srcX, srcY, w, h, pct)</h4>
|
||
|
||
<p> <code>gd.copyMerge</code> is almost identical to <code>gd.copy</code>,
|
||
except that it 'merges' the two images by an amount specified in the
|
||
last parameter. If the last parameter is 100, then it will method
|
||
identically to <code>gd.copy</code> - the source image replaces the
|
||
pixels in the destination.</p>
|
||
|
||
<p> If, however, the pct parameter is less than 100, then the two images
|
||
are merged. With pct = 0, no action is taken. </p>
|
||
|
||
<p> This feature is most useful to 'highlight' sections of an image by
|
||
merging a solid color with pct = 50.</p>
|
||
|
||
|
||
|
||
<h4>gd.copyMergeGray(dstImage, srcImage, dstX, dstY, srcX, srcY, w, h, pct)<br>
|
||
dstImage:copyMergeGray(srcImage, dstX, dstY, srcX, srcY, w, h, pct)</h4>
|
||
|
||
<p> <code>gd.copyMergeGray</code> is almost identical to
|
||
<code>gd.copyMerge</code>, except that when merging images it preserves
|
||
the hue of the source by converting the destination pixels to grey scale
|
||
before the copy operation. <p>
|
||
|
||
|
||
|
||
<h4>gd.paletteCopy(dstImage, srcImage)<br>
|
||
dstImage:paletteCopy(srcImage)</h4>
|
||
|
||
<p> <code>gd.paletteCopy</code> copies a palette from one image to another,
|
||
attempting to match the colors in the target image to the colors in the
|
||
source palette. </p>
|
||
|
||
|
||
|
||
<h4>gdImage:squareToCircle(radius)</h4>
|
||
|
||
<p> Returns a new image of width and height radius * 2, in which the X
|
||
axis of the original has been remapped to <em>theta</em> (angle) and the
|
||
Y axis of the original has been remapped to <em>rho</em> (distance from
|
||
center). This is known as a "polar coordinate transform". The image
|
||
<b>MUST</b> be square, but can have any size. </p>
|
||
|
||
|
||
|
||
<h4>gdImage:sharpen(pct)</h4>
|
||
|
||
<p> Sharpens the specified image. <b>pct</b> is a sharpening percentage,
|
||
and can be greater than 100. Silently does nothing to non-truecolor
|
||
images. Silently does nothing for <b>pct</b> < 0. Transparency/alpha
|
||
channel are not altered. </p>
|
||
|
||
|
||
|
||
<h4>gdImage:trueColorToPalette(dither, colorsWanted)</h4>
|
||
|
||
<p> This method converts a truecolor image to a palette-based image,
|
||
using a high-quality two-pass quantization routine. If <b>dither</b>
|
||
is set to <b>true</b>, the image will be dithered to approximate colors
|
||
better, at the expense of some obvious "speckling". <b>colorsWanted</b>,
|
||
an integer value, can be anything up to 256. If the original source image
|
||
includes photographic information or anything that came out of a JPEG,
|
||
256 is strongly recommended. 100% transparency of a single transparent
|
||
color in the original truecolor image will be preserved. There is no
|
||
other support for preservation of alpha channel or transparency in the
|
||
destination image. </p>
|
||
|
||
<p> For best results, don't use this method -- write real truecolor
|
||
PNGs and JPEGs. The disk space gain of conversion to palette is not great
|
||
(for small images it can be negative) and the quality loss is ugly. </p>
|
||
|
||
|
||
|
||
|
||
<a name="api.gifanim"></a>
|
||
<h3>GIF animation methods</h3>
|
||
|
||
<h4>gdImage:gifAnimBegin(filename, globalCM, loops)</h4>
|
||
|
||
<p> This method must be called as the first method when creating a GIF
|
||
animation in a file on the disk. It writes the correct GIF file headers
|
||
to file name <b>filename</b> and prepares for frames to be added for
|
||
the animation. The image argument is not used to produce an image frame
|
||
to the file, it is only used to establish the GIF animation frame size,
|
||
interlacing options and the color palette. <code>gd.gifAnimAdd</code>
|
||
is used to add the first and subsequent frames to the animation, and
|
||
the animation must be terminated by calling <code>gd.gifAnimEnd</code>,
|
||
passing the same file name. </p>
|
||
|
||
<p> The <b>GlobalCM</b> flag indicates if a global color map (or palette)
|
||
is used in the GIF89A header. A <b>true</b> value specifies that a
|
||
global color map should be used to reduce the size of the animation. Of
|
||
course, if the color maps of individual frames differ greatly, a global
|
||
color map may not be a good idea, so you should use <b>globalCM</b> =
|
||
<b>false</b>. </p>
|
||
|
||
<p> If <b>loops</b> is 0 or greater, the Netscape 2.0 extension for
|
||
animation loop count is written. 0 means infinite loop count. -1 means
|
||
that the extension is not added which results in no looping. -1 is
|
||
the default. </p>
|
||
|
||
|
||
|
||
<h4>gdImage:gifAnimBeginStr(globalCM, loops)</h4>
|
||
|
||
<p> This method must be called as the first method when creating a GIF
|
||
animation in memory. It returns the correct GIF file headers as an Lua
|
||
string and prepares for frames to be added for the animation. The image
|
||
argument is not used to produce an image frame to the file, it is only
|
||
used to establish the GIF animation frame size, interlacing options
|
||
and the color palette. New frames must be created with the method
|
||
<code>gd.gifAnimAddStr</code> and concatened to this one. Finally,
|
||
one last frame, generated with the method <code>gd.gifAnimEndStr</code>,
|
||
must be concatened to finish the animation. </p>
|
||
|
||
<p> The <b>GlobalCM</b> flag indicates if a global color map (or palette)
|
||
is used in the GIF89A header. A <b>true</b> value specifies that a
|
||
global color map should be used to reduce the size of the animation. Of
|
||
course, if the color maps of individual frames differ greatly, a global
|
||
color map may not be a good idea, so you should use <b>globalCM</b> =
|
||
<b>false</b>. </p>
|
||
|
||
<p> If <b>loops</b> is 0 or greater, the Netscape 2.0 extension for
|
||
animation loop count is written. 0 means infinite loop count. -1 means
|
||
that the extension is not added which results in no looping. -1 is
|
||
the default. </p>
|
||
|
||
|
||
|
||
<h4>gdImage:gifAnimAdd(filename, localCM, leftOfs, topOfs, delay, disposal [, previm])</h4>
|
||
|
||
<p> This method writes GIF animation frames to the file specified by
|
||
<b>filename</b>, which was created with <code>gd.gifAnimBegin</code>. With
|
||
<b>leftOfs</b> and <b>topOfs</b> you can place this frame in
|
||
different offset than (0, 0) inside the image screen as defined
|
||
in <code>gd.gifAnimBegin</code>. Delay between the previous
|
||
frame and this frame is in 1/100s units. Disposal is usually
|
||
<code>gd.DISPOSAL_NONE</code>, meaning that the pixels changed by this
|
||
frame should remain on the display when the next frame begins to render,
|
||
but can also be <code>gd.DISPOSAL_UNKNOWN</code> (not recommended),
|
||
<code>gd.DISPOSAL_RESTORE_BACKGROUND</code> (restores the first allocated
|
||
color of the global palette), or <code>gd.DISPOSAL_RESTORE_PREVIOUS</code>
|
||
(restores the appearance of the affected area before the frame was
|
||
rendered). Only <code>gd.DISPOSAL_NONE</code> is a sensible choice for the
|
||
first frame. If <b>previm</b> is passed, the built-in GIF optimizer will
|
||
always use <code>gd.DISPOSAL_NONE</code> regardless of the <b>disposal</b>
|
||
parameter. </p>
|
||
|
||
<p> Setting the <b>localCM</b> flag to <b>true</b> adds a local
|
||
palette for this image to the animation. Otherwise the global palette
|
||
is assumed and the user must make sure the palettes match. Use
|
||
<code>gd.paletteCopy</code> to do that. </p>
|
||
|
||
<p> Automatic optimization is activated by giving the previous
|
||
image as a parameter. This method then compares the images and
|
||
only writes the changed pixels to the new frame in animation. The
|
||
<b>disposal</b> parameter for optimized animations must be set to
|
||
<code>gd.DISPOSAL_NONE</code>, also for the first frame. <b>leftOfs</b>
|
||
and <b>topOfs</b> parameters are ignored for optimized frames. To achieve
|
||
good optimization, it is usually best to use a single global color map. To
|
||
allow <code>gd.gifAnimAdd</code> to compress unchanged pixels via the use
|
||
of a transparent color, the image must include a transparent color.</p>
|
||
|
||
|
||
|
||
|
||
<h4>gdImage:gifAnimAddStr(localCM, leftOfs, topOfs, delay, disposal [, previm])</h4>
|
||
|
||
<p> This method returns GIF animation frames as Lua
|
||
strings to be concatenated to headers which was created with
|
||
<code>gd.gifAnimBeginStr</code>. With <b>leftOfs</b> and <b>topOfs</b>
|
||
you can place this frame in different offset than (0, 0) inside the image
|
||
screen as defined in <code>gd.gifAnimBegin</code>. Delay between the
|
||
previous frame and this frame is in 1/100s units. Disposal is usually
|
||
<code>gd.DISPOSAL_NONE</code>, meaning that the pixels changed by this
|
||
frame should remain on the display when the next frame begins to render,
|
||
but can also be <code>gd.DISPOSAL_UNKNOWN</code> (not recommended),
|
||
<code>gd.DISPOSAL_RESTORE_BACKGROUND</code> (restores the first allocated
|
||
color of the global palette), or <code>gd.DISPOSAL_RESTORE_PREVIOUS</code>
|
||
(restores the appearance of the affected area before the frame was
|
||
rendered). Only <code>gd.DISPOSAL_NONE</code> is a sensible choice for the
|
||
first frame. If <b>previm</b> is passed, the built-in GIF optimizer will
|
||
always use <code>gd.DISPOSAL_NONE</code> regardless of the <b>disposal</b>
|
||
parameter. </p>
|
||
|
||
<p> Setting the <b>localCM</b> flag to <b>true</b> adds a local
|
||
palette for this image to the animation. Otherwise the global palette
|
||
is assumed and the user must make sure the palettes match. Use
|
||
<code>gd.paletteCopy</code> to do that. </p>
|
||
|
||
<p> Automatic optimization is activated by giving the previous
|
||
image as a parameter. This method then compares the images and
|
||
only writes the changed pixels to the new frame in animation. The
|
||
<b>disposal</b> parameter for optimized animations must be set to
|
||
<code>gd.DISPOSAL_NONE</code>, also for the first frame. <b>leftOfs</b>
|
||
and <b>topOfs</b> parameters are ignored for optimized frames. To achieve
|
||
good optimization, it is usually best to use a single global color map. To
|
||
allow <code>gd.gifAnimAdd</code> to compress unchanged pixels via the use
|
||
of a transparent color, the image must include a transparent color.</p>
|
||
|
||
|
||
<h4>gdImage:gifAnimEnd(filename)</h4>
|
||
|
||
<p> Finishes a GIF animation properly by writing a semicolon character
|
||
(;) to the output file. You must call this method (or write the semicolon
|
||
by yourself) to create valid animations. </p>
|
||
|
||
|
||
|
||
<h4>gdImage:gifAnimEndStr()</h4>
|
||
|
||
<p> Returns a semicolon character (;) as a Lua string, which must
|
||
be concatened as the last element of an animation created with
|
||
<code>gd.gifAnimBeginStr</code> and <code>gd.gifAnimAddStr</code>. Of
|
||
course, you can concatenate a semicolon by yourself, but this is a more
|
||
explicit way to finish the animation. </p>
|
||
|
||
|
||
|
||
|
||
<a name="examples"></a>
|
||
<h2>Examples</h2>
|
||
|
||
<a name="examples.counter"></a>
|
||
<h3>CGI Web Counter</h3>
|
||
<pre class="example2">
|
||
#!/usr/bin/env lua
|
||
-- counter.lua -- a web counter in Lua!
|
||
-- (c) 2004 Alexandre Erwin Ittner
|
||
|
||
require "gd"
|
||
|
||
datafile = "counter.txt"
|
||
fp = io.open(datafile, "r+")
|
||
if fp then
|
||
cnt = tonumber(fp:read("*l")) or 0
|
||
fp:seek("set", 0)
|
||
else
|
||
cnt = 0
|
||
fp = io.open(datafile, "w")
|
||
assert(fp)
|
||
end
|
||
cnt = cnt + 1
|
||
fp:write(cnt .."\n")
|
||
fp:close()
|
||
|
||
sx = math.max(string.len(tostring(cnt)), 1) * 8
|
||
im = gd.create(sx, 15)
|
||
-- first allocated color defines the background.
|
||
white = im:colorAllocate(255, 255, 255)
|
||
im:colorTransparent(white)
|
||
black = im:colorAllocate(0, 0, 0)
|
||
im:string(gd.FONT_MEDIUM, 1, 1, cnt, black)
|
||
|
||
print("Content-type: image/png\n")
|
||
io.write(im:pngStr())
|
||
</pre>
|
||
|
||
|
||
<a name="examples.clock"></a>
|
||
<h3>CGI Analog clock</h3>
|
||
|
||
<img src="clock-example.png" alt="Clock Example output"
|
||
title="Clock Example output">
|
||
|
||
<pre class="example2">
|
||
#!/usr/bin/env lua
|
||
|
||
-- a cgi script that draws an analog clock with lua and lua-gd
|
||
-- (c) 2004 Alexandre Erwin Ittner
|
||
|
||
require "gd"
|
||
|
||
function createClock(size, hours, minutes)
|
||
local im = gd.createTrueColor(size, size)
|
||
local white = im:colorAllocate(255, 255, 255)
|
||
local gray = im:colorAllocate(128, 128, 128)
|
||
local black = im:colorAllocate(0, 0, 0)
|
||
local blue = im:colorAllocate(0, 0, 128)
|
||
local cxy = size/2
|
||
|
||
im:filledRectangle(0, 0, size, size, white)
|
||
im:setThickness(math.max(1, size/100))
|
||
im:arc(cxy, cxy, size, size, 0, 360, black)
|
||
|
||
local ang = 0
|
||
local rang, gsize
|
||
while ang < 360 do
|
||
rang = math.rad(ang)
|
||
if math.mod(ang, 90) == 0 then
|
||
gsize = 0.75
|
||
else
|
||
gsize = 0.85
|
||
end
|
||
im:line(
|
||
cxy + gsize * cxy * math.sin(rang),
|
||
size - (cxy + gsize * cxy * math.cos(rang)),
|
||
cxy + cxy * 0.9 * math.sin(rang),
|
||
size - (cxy + cxy * 0.9 * math.cos(rang)),
|
||
gray)
|
||
ang = ang + 30
|
||
end
|
||
|
||
im:setThickness(math.max(1, size/50))
|
||
im:line(cxy, cxy,
|
||
cxy + 0.45 * size * math.sin(math.rad(6*minutes)),
|
||
size - (cxy + 0.45 * size * math.cos(math.rad(6*minutes))),
|
||
blue)
|
||
|
||
im:setThickness(math.max(1, size/25))
|
||
rang = math.rad(30*hours + minutes/2)
|
||
im:line(cxy, cxy,
|
||
cxy + 0.25 * size * math.sin(rang),
|
||
size - (cxy + 0.25 * size * math.cos(rang)),
|
||
blue)
|
||
|
||
im:setThickness(1)
|
||
local sp = math.max(1, size/20)
|
||
im:filledArc(cxy, cxy, sp, sp, 0, 360, black, gd.ARC)
|
||
|
||
return im
|
||
end
|
||
|
||
dh = os.date("*t")
|
||
im = createClock(100, dh.hour, dh.min)
|
||
|
||
print("Content-type: image/png")
|
||
print("Refresh: 60") -- Ask browser to reload the image after 60s
|
||
print("Pragma: no-cache") -- Can mozilla understand this?
|
||
print("Expires: Thu Jan 01 00:00:00 UTC 1970") -- Marks as expired
|
||
print("")
|
||
|
||
io.write(im:pngStr())
|
||
</pre>
|
||
|
||
|
||
<a name="examples.fractal"></a>
|
||
<h3>The Sierpinski triangle</h3>
|
||
|
||
<img src="sierpinski.png" width="250" height="250"
|
||
alt="The Sierpinski triangle" title="The Sierpinski triangle">
|
||
|
||
<pre class="example2">
|
||
#!/usr/bin/env lua
|
||
-- Draws the famous Sierpinski triangle with lua-gd
|
||
|
||
require "gd"
|
||
|
||
size = 250
|
||
im = gd.createPalette(size, size)
|
||
white = im:colorAllocate(255, 255, 255)
|
||
black = im:colorAllocate(0, 0, 0)
|
||
|
||
m = {}
|
||
m[math.floor(size/2)] = true
|
||
|
||
for i = 1, size do
|
||
n = {}
|
||
for j = 1, size do
|
||
if m[j] then
|
||
im:setPixel(j, i, black)
|
||
n[j+1] = not n[j+1]
|
||
n[j-1] = not n[j-1]
|
||
end
|
||
end
|
||
m = n
|
||
end
|
||
|
||
im:png("sierpinski.png")
|
||
</pre>
|
||
|
||
|
||
|
||
|
||
<a name="examples.fontconfig"></a>
|
||
<h3>Using Freetype, Fontconfig and TrueType fonts</h3>
|
||
|
||
<img src="fontconfig-example.png" alt="Fontconfig Example output"
|
||
title="Fontconfig Example output">
|
||
|
||
<pre class="example2">
|
||
-- The fonts used in this example comes with Microsoft operating systems
|
||
-- and can be downloaded from http://corefonts.sourceforge.net
|
||
|
||
require "gd"
|
||
|
||
im = gd.createTrueColor(220, 190)
|
||
white = im:colorAllocate(255, 255, 255)
|
||
black = im:colorAllocate(0, 0, 0)
|
||
x, y = im:sizeXY()
|
||
im:filledRectangle(0, 0, x, y, white)
|
||
|
||
gd.useFontConfig(true)
|
||
im:stringFT(black, "Arial", 20, 0, 10, 30, "Standard Arial")
|
||
im:stringFT(black, "Arial:bold", 20, 0, 10, 60, "Bold Arial")
|
||
im:stringFT(black, "Arial:italic", 20, 0, 10, 90, "Italic Arial")
|
||
im:stringFT(black, "Arial:bold:italic", 20, 0, 10, 120, "Italic Bold Arial")
|
||
im:stringFT(black, "Times New Roman", 20, 0, 10, 150, "Times New Roman")
|
||
im:stringFT(black, "Comic Sans MS", 20, 0, 10, 180, "Comic Sans MS")
|
||
|
||
im:png("out.png")
|
||
</pre>
|
||
|
||
|
||
|
||
<a name="examples.gifanim"></a>
|
||
<h3>GIF animation</h3>
|
||
|
||
<img src="gifanim.gif" width="120" height="120"
|
||
alt="A GIF animation" title="A GIF animation">
|
||
|
||
<pre class="example2">
|
||
require "gd"
|
||
|
||
im = gd.createPalette(120, 120)
|
||
assert(im)
|
||
|
||
black = im:colorAllocate(0, 0, 0)
|
||
blue = {}
|
||
for i = 1, 20 do
|
||
blue[i] = im:colorAllocate(0, 0, 120+6*i)
|
||
end
|
||
|
||
fp = io.open("out.gif", "w")
|
||
assert(fp, "Failed to open file for writting")
|
||
|
||
fp:write(im:gifAnimBeginStr(true, 0))
|
||
|
||
for i = 1, 20 do
|
||
tim = gd.createPalette(120, 120)
|
||
tim:paletteCopy(im)
|
||
tim:arc(60, 60, 6*i, 6*i, 0, 360, blue[21-i])
|
||
fp:write(tim:gifAnimAddStr(false, 0, 0, 5, gd.DISPOSAL_NONE))
|
||
end
|
||
|
||
fp:write(gd.gifAnimEndStr())
|
||
fp:close()
|
||
</pre>
|
||
|
||
|
||
|
||
<a name="examples.steg"></a>
|
||
<h3>A Steganography Application</h3>
|
||
|
||
<table border="0">
|
||
<tr>
|
||
<td width="216">
|
||
<img src="cat.png" width="216" height="256" alt="Original test image.">
|
||
</td>
|
||
<td width="216">
|
||
<img src="catmsg.png" width="216" height="256" alt="Image with a staganographic message">
|
||
</td>
|
||
<td width="216">
|
||
<img src="catdiff.png" width="216" height="256" alt="Resulting image from 'steg.lua diff'">
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td width="216"> Original test image. </td>
|
||
<td width="216"> Image with a staganographic message (the message cause no
|
||
visible changes).</td>
|
||
<td width="216"> Resulting image from <code>"steg.lua diff"</code>
|
||
showing, in color, the pixels changed to store the message. </td>
|
||
</tr>
|
||
</table>
|
||
|
||
<pre class="example2">
|
||
#/usr/bin/env lua
|
||
--[[
|
||
Steganography with Lua-GD
|
||
|
||
Steganography is the technique of writing hidden messages in such a way
|
||
that no one apart from the intended recipient knows of the existence of
|
||
the message; this is in contrast to cryptography, where the existence
|
||
of the message is clear, but the meaning is obscured. Generally a
|
||
steganographic message will appear to be something else, like a shopping
|
||
list, an article, a picture, or some other "cover" message. In the
|
||
digital age, steganography works by replacing bits of useless or unused
|
||
data in regular computer files (such as graphics, sound, text, HTML, or
|
||
even floppy disks) with bits of different, invisible information. This
|
||
hidden information can be plain text, cipher text or even images.
|
||
|
||
|
||
A Simple Example
|
||
|
||
If Alice wants to send a secret message to Bob through an insecure
|
||
channel, she can use some encryption software (like GnuPG) to encrypt
|
||
the message with Bob's public key. It's a good solution because no
|
||
one unless Bob will be able to read the message. She can also sign the
|
||
message so Bob will know that the message really comes from her. BUT,
|
||
a potential attacker will know that a ciphered message was sent. If the
|
||
attacker has control over the communication channel, he might block the
|
||
message in some way that Bob will never receive it. If Alice also HIDES
|
||
the ciphertext in an unsuspected piece of information (like a photo of her
|
||
cat) the attacker will not detect it and the message will arrive to Bob.
|
||
|
||
This program will help Alice to hide some arbitrary text in a PNG image by
|
||
replacing the least significant bits of each color channel of some pixels
|
||
with bits from the encrypted message. PNG or other loseless compression
|
||
algorithm are mandatory here, since compressing the image with a lossy
|
||
algorithm will destroy the stored information. The maximum length of the
|
||
message is limited by the image's size (each byte needs 8 color channels or
|
||
2 pixels and 2 channels from the next pixel). So, the image must have at
|
||
least "ceil((length+1)*8/3)" pixels (the extra byte is the NUL marker for
|
||
the end of the string). So, if Alice's message is "Meet me in the secret
|
||
place at nine o'clock.", she will encrypt and sign it to something like
|
||
"PyJYDpz5LCOSHPiXDvLHmVzxLV8qS7EFvZnoo1Mxk+BlT+7lMjpQKs" (imagine Alice's
|
||
cat walking in you keyboard :). This is the ciphertext that will be sent
|
||
to Bob through the image.
|
||
|
||
The following table shows what happens to the first eight pixels from
|
||
the image when mixed to the first three bytes from the encrypted message:
|
||
|
||
|
||
+-----+---+----------+-----------------+----------+
|
||
| Pix | C | Orig img | Message | New img |
|
||
| # | | bits | Chr | Dec | Bin | bits |
|
||
+-----+---+----------+-----+-----+-----+----------+
|
||
| | R | 01010010 | | | 0 | 01010010 |
|
||
| 1 | G | 00101010 | | | 1 | 00101011 |
|
||
|_____| B | 00010101 | | | 0 | 00010100 |
|
||
| | R | 11100100 | P | 080 | 1 | 11100101 |
|
||
| 2 | G | 00100100 | | | 0 | 00100100 |
|
||
|_____| B | 01001111 | | | 0 | 01001110 |
|
||
| | R | 01010010 | | | 0 | 01010010 |
|
||
| 3 | G | 00101110 |_____|_____|__0__| 00101110 |
|
||
|_____| B | 00111001 | | | 0 | 00111000 |
|
||
| | R | 10010110 | | | 1 | 10010111 |
|
||
| 4 | G | 01011101 | | | 1 | 01011101 |
|
||
|_____| B | 00100101 | y | 121 | 1 | 00100101 |
|
||
| | R | 01001001 | | | 1 | 01001001 |
|
||
| 5 | G | 10110110 | | | 0 | 10110110 |
|
||
|_____| B | 00010101 | | | 0 | 00010100 |
|
||
| | R | 00110100 |_____|_____|__1__| 00110101 |
|
||
| 6 | G | 01000111 | | | 0 | 01000110 |
|
||
|_____| B | 01001000 | | | 1 | 01001001 |
|
||
| | R | 01010110 | | | 0 | 01010110 |
|
||
| 7 | G | 00011001 | | | 0 | 00011000 |
|
||
|_____| B | 10010100 | J | 074 | 1 | 10010101 |
|
||
| | R | 00010101 | | | 0 | 00010100 |
|
||
| 8 | G | 01011010 | | | 1 | 01011011 |
|
||
| | B | 01010001 | | | 0 | 01010000 |
|
||
+-----+---+----------+-----+-----+-----+----------+
|
||
|
||
|
||
When Bob wants to read the message he will extract the least significant
|
||
bit (LSB) from each color channel from some pixels of the image and
|
||
join them to get the original ciphertext. A NULL character (ASCII #0)
|
||
will mark the end of the message within the image, so he will know when
|
||
to stop. Of course, this program will also do this boring job for Bob.
|
||
|
||
--]]
|
||
|
||
require "gd"
|
||
|
||
function getLSB(n)
|
||
return math.mod(n, 2) ~= 0
|
||
end
|
||
|
||
|
||
-- Bizarre way to do some bit-level operations without bitlib.
|
||
function setLSB(n, b)
|
||
if type(b) == "number" then
|
||
if b == 0 then
|
||
b = false
|
||
else
|
||
b = true
|
||
end
|
||
end
|
||
if getLSB(n) then
|
||
if b then
|
||
return n
|
||
elseif n > 0 then
|
||
return n - 1
|
||
else
|
||
return n + 1
|
||
end
|
||
else
|
||
if not b then
|
||
return n
|
||
elseif n > 0 then
|
||
return n - 1
|
||
else
|
||
return n + 1
|
||
end
|
||
end
|
||
end
|
||
|
||
|
||
function intToBitArray(n)
|
||
local ret = {}
|
||
local i = 0
|
||
while n ~= 0 do
|
||
ret[i] = getLSB(n)
|
||
n = math.floor(n/2)
|
||
ret.size = i
|
||
i = i + 1
|
||
end
|
||
return ret
|
||
end
|
||
|
||
|
||
function printBitArray(a)
|
||
local i
|
||
for i = a.size,0,-1 do
|
||
if a[i] then
|
||
io.write("1")
|
||
else
|
||
io.write("0")
|
||
end
|
||
end
|
||
end
|
||
|
||
|
||
function mergeMessage(im, msg)
|
||
local w, h = im:sizeXY()
|
||
msg = msg .. string.char(0)
|
||
local len = string.len(msg)
|
||
if h * w < len * 8 then
|
||
return nil
|
||
end
|
||
local x, y = 0, 0
|
||
local oim = gd.createTrueColor(w, h)
|
||
local i = 1
|
||
local a2, c, nc, chr
|
||
local a = {}
|
||
local s, e = 1, 1
|
||
local rgb = {}
|
||
|
||
while y < h do
|
||
c = im:getPixel(x, y)
|
||
rgb.r = im:red(c)
|
||
rgb.g = im:green(c)
|
||
rgb.b = im:blue(c)
|
||
if i <= len and e - s < 3 then
|
||
a2 = intToBitArray(string.byte(string.sub(msg, i, i)))
|
||
for cnt = 7,0,-1 do
|
||
a[e+7-cnt] = a2[cnt]
|
||
end
|
||
i = i + 1
|
||
e = e + 8
|
||
end
|
||
if e - s > 0 then
|
||
rgb.r = setLSB(rgb.r, a[s])
|
||
a[s] = nil
|
||
s = s + 1
|
||
end
|
||
if e - s > 0 then
|
||
rgb.g = setLSB(rgb.g, a[s])
|
||
a[s] = nil
|
||
s = s + 1
|
||
end
|
||
if e - s > 0 then
|
||
rgb.b = setLSB(rgb.b, a[s])
|
||
a[s] = nil
|
||
s = s + 1
|
||
end
|
||
nc = oim:colorResolve(rgb.r, rgb.g, rgb.b)
|
||
oim:setPixel(x, y, nc)
|
||
x = x + 1
|
||
if x == w then
|
||
x = 0
|
||
y = y + 1
|
||
end
|
||
end
|
||
return oim, len*8, w*h
|
||
end
|
||
|
||
|
||
function getMessage(im)
|
||
local msg = {}
|
||
local w, h = im:sizeXY()
|
||
local x, y = 0, 0
|
||
local a = {}
|
||
local s, e = 1, 1
|
||
local b = 0
|
||
local c
|
||
while y <= h do
|
||
c = im:getPixel(x, y)
|
||
a[e] = getLSB(im:red(c))
|
||
a[e+1] = getLSB(im:green(c))
|
||
a[e+2] = getLSB(im:blue(c))
|
||
e = e + 2
|
||
if e - s >= 7 then
|
||
b = 0
|
||
for p = s, s+7 do
|
||
b = b * 2
|
||
if a[p] then
|
||
b = b + 1
|
||
end
|
||
a[p] = nil
|
||
end
|
||
s = s + 8
|
||
if b == 0 then
|
||
return table.concat(msg)
|
||
else
|
||
msg[#msg+1] = string.char(b)
|
||
end
|
||
end
|
||
e = e + 1
|
||
x = x + 1
|
||
if x == w then
|
||
x = 0
|
||
y = y + 1
|
||
end
|
||
end
|
||
return table.concat(msg)
|
||
end
|
||
|
||
|
||
function compare(fimg1, fimg2)
|
||
local im1 = gd.createFromPng(fimg1)
|
||
if not im1 then
|
||
print("ERROR: " .. fimg1 .. " bad PNG data.")
|
||
os.exit(1)
|
||
end
|
||
local im2 = gd.createFromPng(fimg2)
|
||
if not im2 then
|
||
print("ERROR: " .. fimg2 .. " bad PNG data.")
|
||
os.exit(1)
|
||
end
|
||
local w1, h1 = im1:sizeXY()
|
||
local w2, h2 = im2:sizeXY()
|
||
if w1 ~= w2 or h1 ~= h2 then
|
||
print("ERROR: Images have different sizes.")
|
||
os.exit(1)
|
||
end
|
||
local oim = gd.createTrueColor(w1, h1)
|
||
local x, y = 0, 0
|
||
local c1, c2, oc, f, fc
|
||
while y < h1 do
|
||
c1 = im1:getPixel(x, y)
|
||
c2 = im2:getPixel(x, y)
|
||
if im1:red(c1) ~= im2:red(c2)
|
||
or im1:green(c1) ~= im2:green(c2)
|
||
or im1:blue(c1) ~= im2:blue(c2) then
|
||
oc = oim:colorResolve(im2:red(c2), im2:green(c2), im2:blue(c2))
|
||
oim:setPixel(x, y, oc)
|
||
else
|
||
f = math.floor((im1:red(c1) + im1:green(c1) + im1:blue(c1))/6.0)
|
||
fc = oim:colorResolve(f, f, f)
|
||
oim:setPixel(x, y, fc)
|
||
end
|
||
x = x + 1
|
||
if x == w1 then
|
||
x = 0
|
||
y = y + 1
|
||
end
|
||
end
|
||
return oim
|
||
end
|
||
|
||
|
||
function usage()
|
||
print("Usage:")
|
||
print(" lua steg.lua hide <input file> <output file>")
|
||
print(" lua steg.lua show <input file>")
|
||
print(" lua steg.lua diff <input file 1> <input file 2> <output file>")
|
||
print("")
|
||
print(" hide - Reads a message from stdin and saves into <output file>.")
|
||
print(" show - Reads a message from <input file> and prints it to stdout.")
|
||
print(" diff - Compares two images and writes the diff to <output file>.")
|
||
print("")
|
||
print(" WARNING: All files used here must be in the PNG format!")
|
||
end
|
||
|
||
|
||
if not arg[1] or not arg[2] then
|
||
usage()
|
||
os.exit(1)
|
||
end
|
||
|
||
if arg[1] == "show" then
|
||
im = gd.createFromPng(arg[2])
|
||
if not im then
|
||
print("ERROR: Bad image data.")
|
||
os.exit(1)
|
||
end
|
||
io.write(getMessage(im))
|
||
os.exit(0)
|
||
end
|
||
|
||
if arg[1] == "hide" then
|
||
if not arg[3] then
|
||
usage()
|
||
os.exit(1)
|
||
end
|
||
im = gd.createFromPng(arg[2])
|
||
if not im then
|
||
print("ERROR: Bad image data.")
|
||
os.exit(1)
|
||
end
|
||
print("Type your message and press CTRL+D to finish.")
|
||
msg = io.read("*a")
|
||
oim, l, t = mergeMessage(im, msg)
|
||
if not oim then
|
||
print("ERROR: Image is too small for the message.")
|
||
os.exit(1)
|
||
end
|
||
if not oim:png(arg[3]) then
|
||
print("ERROR: Failed to write output file.")
|
||
os.exit(1)
|
||
end
|
||
print(string.format("DONE: %2.1f%% of the image used to store the message.",
|
||
100.0*l/t))
|
||
os.exit(0)
|
||
end
|
||
|
||
if arg[1] == "diff" then
|
||
if not arg[3] and arg[4] then
|
||
usage()
|
||
os.exit(1)
|
||
end
|
||
oim = compare(arg[2], arg[3])
|
||
if not oim:png(arg[4]) then
|
||
print("ERROR: Failed to write output file.")
|
||
os.exit(1)
|
||
end
|
||
os.exit(0)
|
||
end
|
||
|
||
usage()
|
||
os.exit(1)
|
||
</pre>
|
||
|
||
|
||
|
||
<a name="examples.other"></a>
|
||
<h3>Other examples</h3>
|
||
<p> There are some useful examples in the <code>demos</code> directory
|
||
within the distribution package. </p>
|
||
|
||
|
||
|
||
<a name="contact"></a>
|
||
<h2>Contact information</h2>
|
||
|
||
<p>
|
||
Author: <b>Alexandre Erwin Ittner</b>
|
||
<br> E-mail: <a href="mailto:aittner#netuno.com.br">aittner<b>#</b>netuno.com.br</a>
|
||
(e-mail obfuscated to avoid spam-bots. Please replace the "#" with an "@").
|
||
|
||
<br> GnuPG/PGP Key: <a href="http://users.netuno.com.br/aittner/AlexandreErwinIttner.pub.asc">0x0041A1FB</a>
|
||
(key fingerprint: <code>9B49 FCE2 E6B9 D1AD 6101 29AD 4F6D F114 0041 A1FB</code>).
|
||
<br> Homepage: <a href="http://users.netuno.com.br/aittner/">http://users.netuno.com.br/aittner/</a>.
|
||
<br> Location: Jaragu<67> do Sul, Santa Catarina, Brazil.
|
||
</p>
|
||
|
||
|
||
<hr>
|
||
$Id: index.html,v 1.67 2006/05/01 00:39:09 dermeister Exp $
|
||
</body>
|
||
</html>
|
||
|
||
|
||
|