403 lines
12 KiB
HTML
403 lines
12 KiB
HTML
<!--startcut ==============================================-->
|
|
<!-- *** BEGIN HTML header *** -->
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
|
<HTML><HEAD>
|
|
<title>Creating/Manipulating images with gd LG #91</title>
|
|
</HEAD>
|
|
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
|
|
ALINK="#FF0000">
|
|
<!-- *** END HTML header *** -->
|
|
|
|
<!-- *** BEGIN navbar *** -->
|
|
<A HREF="price.html"><< Prev</A> | <A HREF="index.html">TOC</A> | <A HREF="../index.html">Front Page</A> | <A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue91/shuveb.html">Talkback</A> | <A HREF="../faq/index.html">FAQ</A> | <A HREF="tranter.html">Next >></A>
|
|
<!-- *** END navbar *** -->
|
|
|
|
<!--endcut ============================================================-->
|
|
|
|
<TABLE BORDER><TR><TD WIDTH="200">
|
|
<A HREF="http://www.linuxgazette.com/">
|
|
<IMG ALT="LINUX GAZETTE" SRC="../gx/2002/lglogo_200x41.png"
|
|
WIDTH="200" HEIGHT="41" border="0"></A>
|
|
<BR CLEAR="all">
|
|
<SMALL>...<I>making Linux just a little more fun!</I></SMALL>
|
|
</TD><TD WIDTH="380">
|
|
|
|
|
|
<CENTER>
|
|
<BIG><BIG><STRONG><FONT COLOR="maroon">Creating/Manipulating images with gd</FONT></STRONG></BIG></BIG>
|
|
<BR>
|
|
<STRONG>By <A HREF="../authors/shuveb.html">Shuveb Hussain</A></STRONG>
|
|
</CENTER>
|
|
|
|
</TD></TR>
|
|
</TABLE>
|
|
<P>
|
|
|
|
<!-- END header -->
|
|
|
|
|
|
|
|
<p>
|
|
gd is an open source library written for easy
|
|
manipulation/creation of images. It lets you open
|
|
images in formats like jpeg,png,xpm and a few more.
|
|
You can think of gd as something like this: It opens
|
|
images in different formats and converts them to
|
|
generic bit-mapped images in memory. It then lets you
|
|
do graphical operations like drawing lines, arcs,
|
|
ellipses or rectangles on that image, and can finally
|
|
store the resulting image back in any of the earlier
|
|
mentioned formats. For exapmple, you could write a
|
|
simple command line program that converts a given file
|
|
in JPEG format to PNG using gd. gd can do more. It can
|
|
change colors in the image, copy,cut, merge or rotate
|
|
it. One more area where gd is useful is when you want
|
|
to create images on the fly. With gd, you can
|
|
programatically create an image, color it, draw on it
|
|
and save it to disk. gd is best known for creating
|
|
images on the fly for use in web pages. This is made
|
|
possible with the help of PHP.
|
|
</p>
|
|
|
|
<p>
|
|
If you got a GNU/Linux system that uses RPM to manage
|
|
packages, try out
|
|
<pre>
|
|
rpm -q gd
|
|
</pre>
|
|
to find out if gd is installed.
|
|
You can download the latest tarball from <a href =
|
|
"http://www.boutell.com"> www.boutell.com </a>
|
|
</p>
|
|
|
|
<h2> Creating Images </h2>
|
|
<p>
|
|
The following program creates a 100 by 100 pixel
|
|
black image with a white line running diagonally
|
|
across it.
|
|
</p>
|
|
<p align=center>
|
|
<IMG ALT="100x100 image created by gd"
|
|
SRC="misc/shuveb/test.jpg" WIDTH="100" HEIGHT="100">
|
|
</p>
|
|
|
|
If you want to save some typing, use <A
|
|
HREF="misc/shuveb/gd-eg1.c.txt">this listing </A>
|
|
|
|
<pre>
|
|
|
|
/* File : gd-eg1.c */
|
|
#include < gd.h >
|
|
#include < stdio.h >
|
|
|
|
int main() {
|
|
gdImagePtr im; //declaration of the image
|
|
FILE *out; //output file
|
|
int black,white;
|
|
|
|
im = gdImageCreate(100,100); //create an image, 100
|
|
by 100 pixels
|
|
|
|
black = gdImageColorAllocate(im, 0, 0, 0); //
|
|
allocate black color
|
|
white = gdImageColorAllocate(im, 255, 255, 255); //
|
|
allocate white color
|
|
gdImageLine(im, 0, 0,100,100, white); // draw a line
|
|
using the allocated white color.
|
|
|
|
out = fopen("test.jpg", "w"); //open a file
|
|
gdImageJpeg(im, out, -1); //write the image to the
|
|
file using the default quality setting
|
|
|
|
/* be good, clean up stuff */
|
|
fclose(out);
|
|
gdImageDestroy(im);
|
|
}
|
|
|
|
</pre>
|
|
|
|
Compile the program with the following command line:
|
|
<pre>
|
|
|
|
$ gcc gd-eg1.c -lgd
|
|
|
|
</pre>
|
|
|
|
Run the resulting a.out file and you should have a
|
|
test.jpg file created in the current directory. If you
|
|
view it, you'll have a 100 by 100 pixel black image
|
|
with a white line cutting across.
|
|
|
|
The program, I'm sure is simple, butI'll explain the
|
|
code a little.
|
|
<pre>
|
|
gdImagePtr im; //declaration of the image
|
|
</pre>
|
|
|
|
this declares a pointer to a gd image descriptor.
|
|
|
|
<pre>
|
|
im = gdImageCreate(100,100); //create an image, 100
|
|
by 100 pixels
|
|
</pre>
|
|
|
|
we now create an image 100 by 100 pixels and store the
|
|
reference it returns in the variable im. This is much
|
|
like a file handle. All further operations on this
|
|
image shall be carried out using this reference.
|
|
|
|
<pre>
|
|
black = gdImageColorAllocate(im, 0, 0, 0); //
|
|
allocate black color
|
|
white = gdImageColorAllocate(im, 255, 255, 255); //
|
|
allocate white color
|
|
</pre>
|
|
|
|
before you can draw anything on to the image, you'll
|
|
need to allocate color. Allocating color for the first
|
|
time for a newly created image will make it the
|
|
background color for that image. The function
|
|
gdImageColorAllocate takes four arguments. The first
|
|
one is the image pointer and the next three are Red,
|
|
Green and Blue values respectively. Thus calling
|
|
gdImageColorAllocate(im, 0, 0, 0) for the newly
|
|
created image will paint the background of the new
|
|
image black.
|
|
|
|
We store the color indexes in variables because
|
|
graphical drawing or font drawing functions take a
|
|
'color' argument.
|
|
|
|
<pre>
|
|
gdImageLine(im, 0, 0,100,100, white); // draw a line
|
|
using the allocated white color.
|
|
</pre>
|
|
|
|
This function draws a line from the top left
|
|
corner(0,0) to the bottom right corner(100,100) using
|
|
the color white on to the image pointed to by im.
|
|
<pre>
|
|
gdImageJpeg(im, out, -1); //write the image to the
|
|
file using the default quality setting
|
|
</pre>
|
|
|
|
this is the function call that writes the image on to
|
|
a disk file in the JPEG format. The final argument of
|
|
this function is the quality setting for JPEG format
|
|
images. This can be between 1 and 100, where 100 is
|
|
the highest quality. Passing -1 will use the default
|
|
quality setting.
|
|
|
|
Similarly, there are other functions that store images
|
|
in different formats
|
|
|
|
<pre>
|
|
GdImagePng(im,out) // store as PNG (note no quality
|
|
setting)
|
|
GdImageGd and gdImageGd2 are functions that store
|
|
images in formats specified by the library.
|
|
|
|
gdImageDestroy(im);
|
|
</pre>
|
|
<p>
|
|
and you finally release memory allocated to hold the
|
|
image data.
|
|
</p>
|
|
<p>
|
|
Please note that the PNG format is now enjoying good
|
|
support and uses better compression algorithms. It
|
|
also achieves something that the JPEG format does not
|
|
: Transparency.
|
|
GIF format images, though good enough, use the LZW
|
|
compression algorithm patented by Unisys when using
|
|
full compression. The GIF format support in gd was
|
|
thus dropped recently. And you must have read about
|
|
the hue and cry against software patents..... Some web
|
|
sites even claim to be GIF free, like body sprays that
|
|
claim to be "free of CFC, that damages friendly Ozone"
|
|
More on this at <a href
|
|
http://www.burnallgifs.org>www.burnallgifs.org</a>
|
|
|
|
</p>
|
|
|
|
<h2>Manipulating Images</h2>
|
|
|
|
<p>
|
|
gd also allows you to open and manipulate existing
|
|
images apart from creating new ones from scratch. To
|
|
illustrate this, the following program will open an
|
|
image of Tux, enlarge it a little and write a string
|
|
"Tux, the Linux Penguin" on to the image. Apart from
|
|
drawing text on to the image, this program is intended
|
|
to explain a few more functions that will be of use.
|
|
</p>
|
|
Save some typing, use <A
|
|
HREF="misc/shuveb/gd-eg2.c.txt">this listing </A>
|
|
<table align=center border=1>
|
|
<tr>
|
|
<td align=center>Before</td><td
|
|
align=center>After</td>
|
|
</tr>
|
|
<tr><td><IMG ALT="Before manipulation"
|
|
SRC="misc/shuveb/tuxin.jpg"></td><td><IMG ALT="After
|
|
manipulation" SRC="misc/shuveb/tuxout.jpg"></td></tr>
|
|
</tr>
|
|
</table>
|
|
<pre>
|
|
|
|
/* File : gd-eg2.c */
|
|
#include < gd.h >
|
|
#include < stdio.h >
|
|
|
|
int main()
|
|
{
|
|
gdImagePtr oldtux, newtux; //declaration of the image
|
|
pointers
|
|
FILE *out, *in;
|
|
int red,white;
|
|
int brect[8];
|
|
char *err;
|
|
|
|
in = fopen("tuxin.jpg","r");
|
|
oldtux = gdImageCreateFromJpeg(in);
|
|
newtux = gdImageCreate(150,165); //create an image,
|
|
150 by 165 pixels
|
|
|
|
white = gdImageColorAllocate(newtux, 255, 255,
|
|
255);// allocate white color
|
|
red = gdImageColorAllocate(newtux, 255, 0, 0); //
|
|
allocate black color
|
|
|
|
gdImageCopyResized(newtux,oldtux,0,0,0,0,150,150,oldtux->sx,oldtux->sy);
|
|
|
|
err=gdImageStringFT(newtux,brect,
|
|
red,"/usr/X11R6/lib/X11/fonts/TTF/luxisr.ttf",10,0,0,160,"Tux
|
|
,The Linux Penguin");
|
|
if(err) fprintf(stderr,"Error : %s\n",err);
|
|
|
|
out = fopen("tuxout.jpg", "w"); //open a file
|
|
gdImagePng(newtux, out); //write the image to the
|
|
file in the PNG format
|
|
|
|
/* be good, clean up stuff */
|
|
fclose(out);
|
|
fclose(in);
|
|
gdImageDestroy(oldtux);
|
|
gdImageDestroy(newtux);
|
|
}
|
|
|
|
</pre>
|
|
|
|
As you can see, this program uses a few more function
|
|
calls. The functions are described below
|
|
<pre>
|
|
<h3>gdImageCopyResized</h3>
|
|
</pre>
|
|
<p>
|
|
This gd function copies rectangular parts of one
|
|
image to another. In the process of copying, it can
|
|
also resize the image. The function prototype is:
|
|
</p>
|
|
<pre>
|
|
void gdImageCopyResized(gdImagePtr dst, gdImagePtr
|
|
src, int dstX, int dstY, int srcX, int srcY, int
|
|
destW, int destH, int srcW, int srcH);
|
|
</pre>
|
|
<p>
|
|
The sx and sy members of the gdImagePtr structure hold
|
|
the width and height of the image respectively.
|
|
</p>
|
|
|
|
<p>
|
|
You might have noticed that the image becomes tagged
|
|
as a result of stretching. If you have gd version 2.0
|
|
or better, you could rather use gdImageCopyResampled,
|
|
which smoothens rough edges formed as a result of
|
|
stretching or shrinking. If you want to copy portions
|
|
of the image with no resizing involved, then try
|
|
gdImageCopy. To rotate the image as you copy, try the
|
|
new gdImageCopyRotated function.
|
|
</p>
|
|
<pre>
|
|
<h3>gdImageStringFT</h3>
|
|
</pre>
|
|
<p>
|
|
|
|
This function writes text on to the image using the
|
|
freetype library, thus the trailing "FT" in the
|
|
function name. You should have freetype installed and
|
|
your gd library should have been complied with
|
|
freetype support.
|
|
</p>
|
|
|
|
The prototype is:
|
|
<pre>
|
|
char *gdImageStringFT(gdImagePtr im, int *brect, int
|
|
fg, char *fontname, double ptsize, double angle, int
|
|
x, int y, char *string)
|
|
</pre>
|
|
|
|
<p>
|
|
|
|
In difficulty, this function returns a char pointer
|
|
that points to an error message else returns 0. The
|
|
brect array is filled up with the size of the bounding
|
|
rectangle of the printed string. You can also
|
|
determine the size of the bounding rectagle without
|
|
actually printing a string. To do that pass NULL in
|
|
the place of the image pointer argument. For some
|
|
strange reason you need to pass the absolute path of
|
|
the font file to this function. So, even if you have a
|
|
font file in the current directory, you need to
|
|
provide the whole path. Only TTF fonts in this
|
|
function.
|
|
If your needs are simple, you can use the function
|
|
gdImageString. Freetype is not needed for this
|
|
function to work properly, it uses any one of the five
|
|
built in gd fonts.
|
|
</p>
|
|
|
|
|
|
|
|
<!-- *** BEGIN author bio *** -->
|
|
<P>
|
|
<P>
|
|
<!-- *** BEGIN bio *** -->
|
|
<P>
|
|
<img ALIGN="LEFT" ALT="[BIO]" SRC="../gx/2002/note.png">
|
|
<em>
|
|
Shuveb is a pervert by social compulsion sitting in a
|
|
small but historical city in southern India. He thinks
|
|
life is neither a Midsummer Night's Dream nor a
|
|
Tempest, it's simply a Comedy Of Errors, to be lived As
|
|
You Like It. Apart from being a part time philosopher,
|
|
he is a seasoned C programmer who is often in
|
|
confusion about what the * does to a pointer
|
|
variable.... APR Bristol is the company that pays him
|
|
for learning Linux.
|
|
</em>
|
|
<br CLEAR="all">
|
|
<!-- *** END bio *** -->
|
|
|
|
<!-- *** END author bio *** -->
|
|
|
|
|
|
<!-- *** BEGIN copyright *** -->
|
|
<hr>
|
|
<CENTER><SMALL><STRONG>
|
|
Copyright © 2003, Shuveb Hussain.
|
|
Copying license <A HREF="../copying.html">http://www.linuxgazette.com/copying.html</A><BR>
|
|
Published in Issue 91 of <i>Linux Gazette</i>, June 2003
|
|
</STRONG></SMALL></CENTER>
|
|
<!-- *** END copyright *** -->
|
|
<HR>
|
|
|
|
<!--startcut ==========================================================-->
|
|
<CENTER>
|
|
<!-- *** BEGIN navbar *** -->
|
|
<A HREF="price.html"><< Prev</A> | <A HREF="index.html">TOC</A> | <A HREF="../index.html">Front Page</A> | <A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue91/shuveb.html">Talkback</A> | <A HREF="../faq/index.html">FAQ</A> | <A HREF="tranter.html">Next >></A>
|
|
<!-- *** END navbar *** -->
|
|
</CENTER>
|
|
</BODY></HTML>
|
|
<!--endcut ============================================================-->
|