Creating the images by means of PHP

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($image192192192); 
// use for drawing 
imageFilledRectangle($image00$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($image192192192); 
$colorForegr       imageColorAllocate($image255255255); 
$colorGrid         imageColorAllocate($image000); 
$colorCross        imageColorAllocate($image000); 
$colorPhysical     imageColorAllocate($image00255); 
$colorEmotional    imageColorAllocate($image25500); 
$colorIntellectual imageColorAllocate($image02550); 

// filling with the background color 
imageFilledRectangle($image00$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($image00$diagramWidth 1$diagramHeight 20
               
$colorGrid); 

// draw the axes 
imageLine($image0, ($diagramHeight 20) / 2$diagramWidth
          (
$diagramHeight 20) / 2$colorCross); 
imageLine($image$diagramWidth 20$diagramWidth 2$diagramHeight 20
          
$colorCross); 
// print the text 
imageString($image31010,  "Birthday: $birthDay.$birthMonth.$birthYear"
            
$colorCross); 
imageString($image31026,  "Today:    ".  date(  "d.m.Y"),  $colorCross); 
imageString($image310$diagramHeight 42,  "Physical"$colorPhysical); 
imageString($image310$diagramHeight 58,  "Emotional"$colorEmotional); 
imageString($image310$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
($daysGone23$colorPhysical); 
drawRhythm($daysGone28$colorEmotional); 
drawRhythm($daysGone33$colorIntellectual); 

for(
$x 0$x $daysToShow$x++) 
    { 
       
        
$phase = (($centerDay $x) % $period) / $period pi(); 
        
        
$y 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 pi(); 
        
        
$y 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($birthdate02); 
$birthDay substr($birthdate32); 
$birthYear substr($birthdate64); 

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($image192192192); 
$colorForegr       imageColorAllocate($image255255255); 
$colorGrid         imageColorAllocate($image000); 
$colorCross        imageColorAllocate($image000); 
$colorPhysical     imageColorAllocate($image00255); 
$colorEmotional    imageColorAllocate($image25500); 
$colorIntellectual imageColorAllocate($image02550); 

// Filling with the background color 
imageFilledRectangle($image00$diagramWidth 1$diagramHeight 1$colorBackgr);  

// Calculate the start date of the graph 
$nrSecondsPerDay 60 60 24
$diagramDate time() - ($daysToShow $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($image3$xCoord 5$diagramHeight 16
                
$thisDate"mday"], $colorGrid); 

    
$diagramDate += $nrSecondsPerDay


// Draw the frame 
imageRectangle($image00$diagramWidth 1$diagramHeight 20
               
$colorGrid); 

// Draw the axes 
imageLine($image0, ($diagramHeight 20) / 2$diagramWidth
          (
$diagramHeight 20) / 2$colorCross); 
imageLine($image$diagramWidth 20$diagramWidth 2$diagramHeight 20
          
$colorCross); 

// Print the text 
imageString($image31010,  "Birthday: $birthDay.$birthMonth.$birthYear"
            
$colorCross); 
imageString($image31026,  "Today:    ".  date(  "d.m.Y"),  $colorCross); 
imageString($image310$diagramHeight 42,  "Physical"$colorPhysical); 
imageString($image310$diagramHeight 58,  "Emotional"$colorEmotional); 
imageString($image310$diagramHeight 74,  "Intellectual"
            
$colorIntellectual); 

// Draw three graphs with corresponding parameters 
drawRhythm($daysGone23$colorPhysical); 
drawRhythm($daysGone28$colorEmotional); 
drawRhythm($daysGone33$colorIntellectual); 

// Send the header Content-type 
//header("Content-type:  image/gif"); 
header("Content-type:  image/png"); 

// Set the interlaced mode 
imageInterlace($image1); 

// Make the background color transparent 
imageColorTransparent($image$colorBackgr); 

// print the image 
//imageGIF($image); 
imagePNG($image); 

?>

 

  • Top