ONLamp.com    
 Published on ONLamp.com (http://www.onlamp.com/)
 See this if you're having trouble printing code examples


Compiling and Enabling GD in PHP 4.3

by Marco Tabini
03/27/2003

The release of version 4.3 of PHP caused a collective sigh of relief from developers who rely on the GD library extension to provide image-manipulation capabilities to their scripts. GD is very powerful, but it can be a real pain to configure and install when compiling the PHP interpreter. Luckily, the latest incarnation of PHP included a built-in version of the library that was supposed to make things easier for everyone.

Unfortunately, this is not necessarily the case. Unless your server is set up in just the right way, if you download the PHP 4.3 source tree from the PHP website and try to compile the GD library into it, you'll still be greeted by a nice set of error messages. My goal with this article is to share my experience in setting up and installing GD and, hopefully, to help you avoid some of the headaches I've had to endure in the process.

GD Components

The problem is that the extension itself is really made of several different components, not all of which are actually included in the PHP distribution package.

The GD library provides the functions necessary to manipulate images, such as by drawing on them, but is unable to convert them to a specific format, say PNG or JPEG, without the help of external libraries. Similarly, GD can draw simple bitmap fonts on a canvas through its own internal functionality, but using TrueType or PostScript Type 1 fonts requires external components as well.

In order to manipulate images in different formats, you will need to download one or more of the following libraries:

FormatLibrary
PNGlibpng
zlib
JPEGjpeglib
XPMlibXpm

Officially, the GD library does not support the GIF format any longer, due to the well-known patent issues that surround it. These days, the PNG format, which is free and generally more efficient than GIF, is the preferred image format of the open source community. However, it's probably fair to say that most web sites still use GIFs. While the ability to read and write PNGs will make it possible for your script to produce images that are compatible with practically all recent browsers, the version of GD that's built into the PHP interpreter still retains the ability to read GIF files--without requiring any external libraries.

If your goal, on the other hand, is to write beautiful text, you may want to install the following libraries:

FormatLibrary
TrueTypeFreeType
TrueTypeFreeType
TrueTypeBuilt-in (requires FreeType)
Type 1 (PostScript)T1Lib

As you can see, there are three different options if you want to be able to display TrueType fonts, and each of them has advantages and drawbacks.

Related Reading

Web Programming CD Bookshelf
Six Bestselling Books on CD-ROM
By A publication of O'Reilly Media

The built-in TrueType functionality is an excellent "quick solution" to the problem of typesetting TrueType fonts. It still requires the presence of the FreeType library on your system, but not of the source code itself. You could easily just install the library from your favourite Linux distribution and simply link the PHP interpreter against it. Chances are that it's already there, if you're running a relatively recent version of X.

FreeType and FreeType2 are two open source typesetting libraries that offer excellent TrueType-rendering capabilities. FreeType is a bit more problematic, because it uses a glyph optimization algorithm that is patented by Apple Computers. As a result, to use FreeType legally, you would either have to pay a royalty to Apple or disable the optimization engine and suffer a lower quality when rendering your fonts, particularly at small point sizes.

FreeType2, on the other hand, does not use any patented optimization techniques. As such, it offers the best possible quality available to render high-quality text.

A Couple of Important Notes

When illustrating compilation examples, I will be listing only ./configure switches necessary for the compilation of the GD extension and its related components. Naturally, you should add any other switches that are required for your particular version of PHP (such as APXS, FTP, and so on). Also, I will reference directories and files outside of the PHP tree as they appear on my computer. Although these may be different on yours, if you follow the instructions, you shouldn't have any problem locating them.

In addition, please don't forget to clean up the PHP tree whenever you run ./configure. I know it's annoying to recompile everything every time. It's also very safe, however, and my experience is that I tend to encounter fewer problems when I do so. You can usually clean the source tree by invoking make as follows:

/marcot/code/php-4.3.0# make clean

Getting Started

The first step towards making GD available to your scripts consists of downloading a copy of PHP 4.3. Besides the additional ease in installing a built-in version of the GD extension, there are many good reasons to upgrade to the latest version of PHP, including a number of bug and security fixes to make your applications safer.

Once you have the PHP source tree in your possession, start by configuring it:

/marcot/code/php-4.3.0# ./configure --with-gd

If the configuration script runs without a glitch, you're a really lucky bird. Chances are that you will receive a number of errors. For example, if the PNG library is installed on your system (and it probably is, if you're running X), configure will find it and try to compile it in:

If configure fails try --with-jpeg-dir=<DIR>
configure: error: PNG support requires ZLIB. Use --with-zlib-dir=<DIR>

As you can see, the script is complaining that we didn't provide it with a location where it could find the ZLIB library, which is required by the PNG component of GD. Wait a moment ... where does the PNG library come from? Simple--it's enabled by default in the source tree whenever you enable GD compilation.

If, on the other hand, PNG is not on your system and you want to use it, you will need to download and install the PNG library. This is not a particularly complex task, but libpng does not use a configuration script. You must copy the appropriate Makefile from the scripts/ directory into the main source tree in order for the compilation to take place:

/marcot/code/php-4.3.0# cd /marcot/code/libpng-1.2.5
/marcot/code/libpng-1.2.5# cp scripts/makefile.linux Makefile
/marcot/code/libpng-1.2.5# make prefix=/usr && make install

If all goes well, the PNG library will be installed and you're on your way. Note that I'm forcing make to use /usr as the prefix for the installation path in order to ensure that the library is installed in the system-wide directories. I will do so with all of the packages that I install in the system. Once this is done, the PHP configuration script should automatically find your PNG library and its header files and compile with it.

The ZLIB library is, most likely, already installed on your computer. You may want to update it to the latest version, since older ones had a buffer overflow problem that could pose a security threat, under certain conditions. If you download the source tarball from the ZLIB web site and untar it, you can compile the library as follows:

/marcot/code/zlib-1.1.4# ./configure --prefix=/usr 
    && make && make install

Finally, you should be able to go back to the PHP source tree and run the configure script again:

/marcot/code/php-4.3.0# ./configure --with-gd 
    --with-zlib-dir=/usr/include

The script should, at this point, run all the way through and write the proper configuration files. You should be able to compile PHP without any problems. The PNG functionality should work just fine--but you still can't produce JPEG images.

Installing JPEG Support

The JPEG library is, perhaps, the easiest component of the GD library to configure and install. I can safely say I've never had any problems with it.

Once you have downloaded the source code, you need to compile and install it:

/marcot/code/jpeg-6b# ./configure --prefix=/usr 
    && make && make install

JPEG has very few external dependencies and the compilation and installation should go through without a hitch. At this point, you're ready to go back to your PHP source tree and re-run configure:

/marcot/code/php-4.3.0# ./configure --with-gd -with-zlib-dir=/usr/include
    --with-jpeg-dir=../jpeg-6b /marcot/code/php-4.3.0# make clean && 
    make && make install

This should result in your PHP engine being neatly reconfigured, compiled, and installed with no problems of any sort.

Getting TrueType Fonts to Work

As I mentioned earlier, the easiest way to provide TrueType rendering capabilities to your scripts is to use the built-in GD library, which requires the FreeType library in order to function properly.

The best way to tell if FreeType is installed on your machine is to check for the freetype.h file. For example, on my machine, I get these results:

/marcot/code/# locate freetype.h
/usr/share/texmf/doc/help/Catalogue/entries/freetype.html
/usr/include/freetype1/freetype/freetype.h
/usr/include/freetype2/freetype/freetype.h

As you can see, both the FreeType and FreeType2 libraries are installed on my server. This is a fairly common result for a RedHat 7.2 or higher machine, as FreeType has been integrated in the X environment to provide support for high-quality TrueType rendering.

If FreeType is not installed on your system, all you need to do is download it, compile it, and install it. You will, however, have to make a decision as to whether you want to compile your version of FreeType with the hinting code that infringes on Apple's patents (for which you will need to buy a license from Apple itself) or not. If you decide to exclude these features, first edit the file ft_conf.h in the FreeType source tree's main directory. In version 1.3.1 of the library, line 98 of that file contains the following:

/* #undef   TT_CONFIG_OPTION_NO_INTERPRETER */

To disable the patent-sensitive functionality and save yourself from having to buy a license, change it as follows:

#define   TT_CONFIG_OPTION_NO_INTERPRETER */

Save the file, and proceed with the configuration and compilation of the library as you would normally:

/marcot/code/freetype-1.3.1# ./configure --prefix=/usr 
    && make && make install

Once FreeType is installed on your system, the PHP configuration script will automatically determine its location. Enabling the built-in TrueType GD functionality only requires the use of a simple switch:

/marcot/code/php-4.3.0# make clean && ./configure 
    --with-gd --with-zlib-dir=/usr/include --enable-gd-native-ttf 
    && make && make install

Depending on the exact version of PHP that you have, the configuration script may not be able to correctly identify the last switch because of a misspelling that existed in its code at some point (and that was fixed a while ago). If --enable-gd-native-ttf fails, try --enable-gd-native-tt instead (without the final f).

If you'd rather use the FreeType library without taking advantage of the built-in TrueType functions, use the following configuration switches:

/marcot/code/php-4.3.0# ./configure --with-gd 
    --with-zlib-dir=../zlib-1.1.4/ --with-freetype=/usr/include/freetype

The installation of support for the FreeType2 library works in a very similar way--you can, in fact, compile both libraries in the GD extension at the same time. This can be useful if some of your older scripts still use FreeType, but you want to use FreeType2 with the new ones, or if you are a hosting provider and want to let your customers use both.

Like its predecessor, FreeType2 is easy to configure and install. Since it does not use any of the patented code from Apple, you don't even have to change any of its source files:

/marcot/code/freetype-2.1.3# ./configure --prefix=/usr 
    && make && make install

FreeType2 support in the GD extension is enabled through a simple command-line switch:

/marcot/code/php-4.3.0# ./configure --with-gd --with-zlib-dir=../zlib-1.1.4/ 
    --with-freetype2=/usr/include/freetype2

Compiling Support for Type1 Fonts

The T1Lib library is used by the GD extension to provide support for PostScript Type1 fonts. This format, very popular among professional typesetters, provides the highest output quality, although the fonts that use it are often expensive. (The X Window System includes a handful of free Type1 fonts.)

As with TrueType, the best way to compile T1Lib into your PHP interpreter is to first verify whether it's already available on your system:

/marcot/code# locate t1lib.h
/usr/include/t1lib.h

If this doesn't work for you, you will need to download and compile it. There are no special requirements for this task. The process is quite straightforward:

/marcot/code/t1lib-1.3.1# ./configure --prefix=/usr 
    && make && make install

As usual, to compile the library within PHP, you will only need a simple ./configure switch:

/marcot/code/php-4.3.0# ./configure --with-gd --with-zlib-dir=../zlib-1.1.4/ 
    --with-t1lib=/usr/include

Putting It All Together

Having covered all of the different options that can be compiled into the GD extension, it's time to compile everything together and test that it works. A complete installation of the GD extension will look similar to the following:

/marcot/code/php-4.3.0# make clean && \
./configure --with-gd --with-zlib-dir=../zlib-1.1.4/ \
--with-jpeg-dir=../jpeg-6b --with-freetype=/usr/include/freetype \
--with-freetype2=/usr/include/freetype2 -with-t1lib=/usr/include && \
make && \
make install

This should result in a complete recompilation and installation of your PHP interpreter with support for GD and all of its ancillary technologies. You can test its functionality through this simple script:

<?php

function test ($string, $test)
{
    echo $string . '... ';

    if ($test)
        echo "success.\n";
    else
        echo "fail.\n";
}

$token = "Testing GD!";

// Create image

$pic = ImageCreate (300, 300); 

test ('Creating image', $pic);

$col2 = ImageColorAllocate ($pic, 0, 0, 100); 
$col1 = ImageColorAllocate ($pic, 200, 200, 200); 

// Test PNG/JPG functionality

ob_start();
$res1 = @ImagePNG ($pic);
$res2 = @ImageJPEG ($pic);
ob_clean();

test ('Testing PNG output', $res1);
test ('Testing JPEG output', $res2);

// Test TrueType functionality

$ttfont = trim (`locate -n 1 .ttf`);

test ('Testing FreeType', @ImageTTFText 
    ($pic, 30, 0, 10, 40, $col1, $ttfont, $token));
test ('Testing FreeType2', @ImageFTText 
    ($pic, 30, 0, 10, 40, $col1, $ttfont, $token, array()));

// Test Type1 functionality

$font = @ImagePsLoadFont (trim (`locate -n 1 .pfb`));

if ($font)
    $res = @ImagePsText ($pic, $token, $font, 10, $col1, $col2, 0, 0);

test ('Testing the Type1 library', ($font && $res));

test ('Destroying image', ImageDestroy($pic)); 

?>

If everything goes according to plan, your PHP interpreter should be able to pass the test with flying colors:

Creating image... success.
Testing PNG output... success.
Testing JPEG output... success.
Testing FreeType... success.
Testing FreeType2... success.
Testing the Type1 library... success.
Destroying image... success.

Marco Tabini specializes in the introduction of open-source products in enterprise environments.


Return to the PHP DevCenter.

Copyright © 2009 O'Reilly Media, Inc.