2745 lines
98 KiB
HTML
Executable File
Raw Permalink Blame History

<!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 &amp; character unless
encoded correctly as <code>&amp;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> &lt; 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 &lt; 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 &gt; 0 then
return n - 1
else
return n + 1
end
else
if not b then
return n
elseif n &gt; 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 &lt; 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 &lt; h do
c = im:getPixel(x, y)
rgb.r = im:red(c)
rgb.g = im:green(c)
rgb.b = im:blue(c)
if i &lt;= len and e - s &lt; 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 &gt; 0 then
rgb.r = setLSB(rgb.r, a[s])
a[s] = nil
s = s + 1
end
if e - s &gt; 0 then
rgb.g = setLSB(rgb.g, a[s])
a[s] = nil
s = s + 1
end
if e - s &gt; 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 &lt;= 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 &gt;= 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 &lt; 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 &lt;input file&gt; &lt;output file&gt;")
print(" lua steg.lua show &lt;input file&gt;")
print(" lua steg.lua diff &lt;input file 1&gt; &lt;input file 2&gt; &lt;output file&gt;")
print("")
print(" hide - Reads a message from stdin and saves into &lt;output file&gt;.")
print(" show - Reads a message from &lt;input file&gt; and prints it to stdout.")
print(" diff - Compares two images and writes the diff to &lt;output file&gt;.")
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>