Creating the images by means of PHP
Aims of that article
In that article we’ll bring up the following questions:
- Headers
- GD library functions using for dynamic creation of images by means of PHP
Header creating
By default PHP prints only one header Content-type: text/html that means that the result of script’s working is HTML code:
<?php
print("Hello world!");
?>
$> php hello.php
Content-type: text/html
Hello world!
$> _
As you can see PHP prints Content-type: text/html and empty line before printing the result of script’s working. For printing the headers in PHP there is used header() function.
<?php
header("Content-type: image/jpeg");
header("Content-type: application/zip");
?>
Sending the header is not enough; you have to specify the printed data format.
Image creating
Image generation includes three main stages:
- Image creating
- Image drawing
- Printing of the image to the browser
For creating the image use ImageCreate() function. Arguments of that function are image width and height in pixels. Function returns the identifier that is used for function calling for working with image.
Before starting drawing you have to register colors that you are going to use. It can be fulfilled by means of ImageColorAllocate() function. Function returns the color identifier that is used in the further operations of image drawing.
Example:
<?php
// register color
$colorHandle = imageColorAllocate($image, 192, 192, 192);
// use for drawing
imageFilledRectangle($image, 0, 0, $diagramWidth - 1, $diagramHeight - 1, $colorBackgr);
?>
Image printing is fulfilled by ImagePNG() or ImageGIF() functions calling. ImageGIF() isn’t supported in the current version of GD. ImagePNG() transforms the internal image to the PNG file and sends it to the client. ImageGIF() works analogously but using GIF format. Before ucing ImagePNG() or ImageGIF() functions you have to send the correspondence Content-type header:
| Format | Header |
| PNG | "Content-type: image/png" |
| GIF | "Content-type: image/gif" |
Notice. Headers relate to the whole document. I .e. if you send the header that shows that you are printing the image, you can’t print the text. If you have printed first byte of the data you can’t change the header! It means that you have to call header() at first and only after that start data printing, otherwise you’ll get an error message. If you don’t send the Content-type header, PHP automatically sends Content-type: text/html.
What’s about practice?
Practical using of the GD library functions we’ll view at the example of the script that construct the graph of biorhythms. Theory of biorhythms says that emotional, physical and intellectual activities cyclically change with some intervals. At the moment of birth these three curves start from the zero point and change during all life.
Every curve has its own cycle:
- Physical : 23 days
- Emotional: 28 days
- Intellectual: 33 days
Curves are sinusoids, that’s why for biorhythm’s value calculation we’ll use function sin().
Date of birth setting
Precedence rule
- Check whether date of birth has been set
- If not show the form for date entering
- After that calculate the amount of days using the Julian calendar.
<?php
if(!isset($birthdate))
{
/* */
}
$daysGone = abs(gregorianToJD($birthMonth, $birthDay, $birthYear)
- gregorianToJD(date( "m"), date( "d"), date( "Y")));
?>
Image preparation
Precedence rule.
Image drawing preparation consists of several GD functions call. The following part of the code:
- Creates the image with required size
- Registers used colors
- Clears the image filling with background color
<?php
// create the image
$image = imageCreate($diagramWidth, $diagramHeight);
// register used colors
$colorBackgr = imageColorAllocate($image, 192, 192, 192);
$colorForegr = imageColorAllocate($image, 255, 255, 255);
$colorGrid = imageColorAllocate($image, 0, 0, 0);
$colorCross = imageColorAllocate($image, 0, 0, 0);
$colorPhysical = imageColorAllocate($image, 0, 0, 255);
$colorEmotional = imageColorAllocate($image, 255, 0, 0);
$colorIntellectual = imageColorAllocate($image, 0, 255, 0);
// filling with the background color
imageFilledRectangle($image, 0, 0, $diagramWidth - 1, $diagramHeight - 1, $colorBackgr);
?>
Draw the frame and print the text
Function ImageString() draws the text line on the image. We have to print five lines. First and second lines will be situated at the top of the image and show birth date and current date, the rest will be situated under the graph and show the colors of biorhythms.
Precedence rule.
- Draw the frame where will be situated graph and axes
- Print the text
<?php
// draw the frame
imageRectangle($image, 0, 0, $diagramWidth - 1, $diagramHeight - 20,
$colorGrid);
// draw the axes
imageLine($image, 0, ($diagramHeight - 20) / 2, $diagramWidth,
($diagramHeight - 20) / 2, $colorCross);
imageLine($image, $diagramWidth / 2, 0, $diagramWidth / 2, $diagramHeight - 20,
$colorCross);
// print the text
imageString($image, 3, 10, 10, "Birthday: $birthDay.$birthMonth.$birthYear",
$colorCross);
imageString($image, 3, 10, 26, "Today: ". date( "d.m.Y"), $colorCross);
imageString($image, 3, 10, $diagramHeight - 42, "Physical", $colorPhysical);
imageString($image, 3, 10, $diagramHeight - 58, "Emotional", $colorEmotional);
imageString($image, 3, 10, $diagramHeight - 74, "Intellectual",
$colorIntellectual);
?>
Pic.1. Biorhythms graph

Draw curves
Biorhythms graphs are the sinusoids, that’s why we’ll use function drawRythm() that shows the sinusoid with given period.
Precedence rule.
- drawRhythm function is called three times with different parameters
- drawRhythm function includes the cycle that calculates the biorhythm value for every day and draws the lines
<?php
drawRhythm($daysGone, 23, $colorPhysical);
drawRhythm($daysGone, 28, $colorEmotional);
drawRhythm($daysGone, 33, $colorIntellectual);
for($x = 0; $x < $daysToShow; $x++)
{
$phase = (($centerDay + $x) % $period) / $period * 2 * pi();
$y = 1 - sin($phase) * (float)$plotScale + (float)$plotCenter;
if($x > 0)
imageLine($image, $oldX, $oldY, $x * $diagramWidth / $daysToShow,
$y, $color);
$oldX = $x * $diagramWidth / $daysToShow;
$oldY = $y;
}
?>
Image printing
So, we have drawn our graph and now we need to send that image to the browser.
Precedence rule.
- Send the header which shows that we print the image in the GIF or PNG formats.
- Define the interlaced format of the image printing
- Make the background color transparent
- Using imageGIF or imagePNG functions print the image
You can’t make changes after imageGIF or imagePNG functions have been called. ImageInterlace() allows setting the interlaced or progressive mode of image print.
ImageColorTransparent() function sets the color of the transparent parts of the image. In our case we use color saved in the $colorBackgr variable.
The full code of the script
<?php
//
// page header
//
function pageHeader()
{
print("<html><head>");
print("<title>Biorhythm with PHP3</title>");
print("</head><body>");
}
//
// page footer
//
function pageFooter()
{
print("</body></html>");
}
//
// function that transforms date from the Julian calendar to the Gregorian calendar
//
function gregorianToJD($month, $day, $year)
{
if($month < 3)
{
$month = $month + 12;
$year = $year - 1;
}
$jd = $day + floor((153 * $month - 457) / 5) + 365 * $year
+ floor($year / 4) - floor($year / 100)
+ floor($year / 400) + 1721118.5;
return($jd);
}
//
// Function of biorhythm graph drawing
// Parameters: day, biorhythm period, color
//
function drawRhythm($daysAlive, $period, $color)
{
global $daysToShow, $image, $diagramWidth, $diagramHeight;
// Define day in the center of the graph
$centerDay = $daysAlive - ($daysToShow / 2);
// Graph’s parameters
$plotScale = ($diagramHeight - 25) / 2;
$plotCenter = ($diagramHeight - 25) / 2;
// Draw the graph
for($x = 0; $x <= $daysToShow; $x++)
{
$phase = (($centerDay + $x) % $period) / $period * 2 * pi();
$y = 1 - sin($phase) * (float)$plotScale + (float)$plotCenter;
if($x > 0)
imageLine($image, $oldX, $oldY, $x * $diagramWidth / $daysToShow,
$y, $color);
// Save the current coordinates
$oldX = $x * $diagramWidth / $daysToShow;
$oldY = $y;
}
}
//
// ---- MAIN PROGRAM START ----
// Check whether date of birth has been set
// If not show the form for date entering
if(!isset($birthdate))
{
pageHeader();
?>
<form method="post" action="<?php print(basename($PHP_SELF)); ?>">
Please enter your birthday:<br>
<input type="text" name="birthdate"
value="MM/DD/YYYY"><input type="submit" value="OK!">
</form>
<?php
pageFooter();
exit();
}
// Select day, month and year
$birthMonth = substr($birthdate, 0, 2);
$birthDay = substr($birthdate, 3, 2);
$birthYear = substr($birthdate, 6, 4);
if(!checkDate($birthMonth, $birthDay, $birthYear))
{
pageHeader();
print("The date "$birthMonth/$birthDay/$birthYear" is invalid.");
pageFooter();
exit();
}
// Graph’s parameters (global variables)
$diagramWidth = 710;
$diagramHeight = 400;
$daysToShow = 30;
$daysGone = abs(gregorianToJD($birthMonth, $birthDay, $birthYear)
- gregorianToJD(date( "m"), date( "d"), date( "Y")));
// Create the image
$image = imageCreate($diagramWidth, $diagramHeight);
// Register the used colors
$colorBackgr = imageColorAllocate($image, 192, 192, 192);
$colorForegr = imageColorAllocate($image, 255, 255, 255);
$colorGrid = imageColorAllocate($image, 0, 0, 0);
$colorCross = imageColorAllocate($image, 0, 0, 0);
$colorPhysical = imageColorAllocate($image, 0, 0, 255);
$colorEmotional = imageColorAllocate($image, 255, 0, 0);
$colorIntellectual = imageColorAllocate($image, 0, 255, 0);
// Filling with the background color
imageFilledRectangle($image, 0, 0, $diagramWidth - 1, $diagramHeight - 1, $colorBackgr);
// Calculate the start date of the graph
$nrSecondsPerDay = 60 * 60 * 24;
$diagramDate = time() - ($daysToShow / 2 * $nrSecondsPerDay) + $nrSecondsPerDay;
for ($i = 1; $i < $daysToShow; $i++)
{
$thisDate = getDate($diagramDate);
$xCoord = ($diagramWidth / $daysToShow) * $i;
imageLine($image, $xCoord, $diagramHeight - 25, $xCoord,
$diagramHeight - 20, $colorGrid);
imageString($image, 3, $xCoord - 5, $diagramHeight - 16,
$thisDate[ "mday"], $colorGrid);
$diagramDate += $nrSecondsPerDay;
}
// Draw the frame
imageRectangle($image, 0, 0, $diagramWidth - 1, $diagramHeight - 20,
$colorGrid);
// Draw the axes
imageLine($image, 0, ($diagramHeight - 20) / 2, $diagramWidth,
($diagramHeight - 20) / 2, $colorCross);
imageLine($image, $diagramWidth / 2, 0, $diagramWidth / 2, $diagramHeight - 20,
$colorCross);
// Print the text
imageString($image, 3, 10, 10, "Birthday: $birthDay.$birthMonth.$birthYear",
$colorCross);
imageString($image, 3, 10, 26, "Today: ". date( "d.m.Y"), $colorCross);
imageString($image, 3, 10, $diagramHeight - 42, "Physical", $colorPhysical);
imageString($image, 3, 10, $diagramHeight - 58, "Emotional", $colorEmotional);
imageString($image, 3, 10, $diagramHeight - 74, "Intellectual",
$colorIntellectual);
// Draw three graphs with corresponding parameters
drawRhythm($daysGone, 23, $colorPhysical);
drawRhythm($daysGone, 28, $colorEmotional);
drawRhythm($daysGone, 33, $colorIntellectual);
// Send the header Content-type
//header("Content-type: image/gif");
header("Content-type: image/png");
// Set the interlaced mode
imageInterlace($image, 1);
// Make the background color transparent
imageColorTransparent($image, $colorBackgr);
// print the image
//imageGIF($image);
imagePNG($image);
?>



