Friday 31 October 2014

PHP Image Creation on RaspberryPi

PHP can harness the power of the GD Graphic Library, allowing the generation and manipulation of images.


You can create images based upon simple lines, rectangles, arcs and circles, as well an manipulating existing graphics files.


So I recently took my first steps in creating images in PHP on a RaspberryPi.

With PHP 5 installed on the RaspberryPi as described in this previous post, I needed to install the GD Graphics LIbrary:-

sudo apt-get install php5-gd

...and then restart the lighttpd service:-

sudo service lighttpd force-reload

In the RaspberryPi web server folder /var/www I created a new file called drawtest.php and wrote a few lines of code:-

<?php
$Image = imagecreate( 500, 500 );
#1st colour allocated is used for the image background
$backColour = imagecolorallocate( $Image, 250, 250, 90 );
#line colours
$colRed = imagecolorallocate( $Image, 250, 0, 0 );
$colBlue = imagecolorallocate( $Image, 0, 0, 250 );
#draw a cross
imageline( $Image, 10, 10, 490, 490, $colRed );
imageline( $Image, 490, 10, 10, 490, $colBlue );
header( "Content-type: image/png" );
imagepng( $Image );
imagedestroy( $Image );
?>


PHP variables have a leading "$" and comments are preceded by "#".

The first line of code uses the method "imagecreate" to create a blank 500x500 image.

I don't understand why imagecreate does not have a 3rd argument for image colour, instead of just accepting the very next colour declaration (imagecolorallocate) to set the image background colour.

The arguments for "imagecolorallocate" specify the red-green-blue values for the new image: $Image.

I also created two additional colours (red & blue) which I use to plot lines using the "imageline" method. This method has four arguments to specify the start and end points for the line in terms of x1, y1, x2, y2.

The top left corner of our image is x=0, y=0, and the bottom right is x=500, y=500.

The method "imagepng" outputs the newly created image in PNG file format, while "imagedestroy" releases the memory previously used by $Image.

So when I point a web browser to this file (e.g. http://192.168.0.31:9080/drawtest.php) the code just generates a yellow box with a red and blue cross:-


Let's plot a graph


I thought I'd try to create a line graph using imageline. My primitive code looks like this:-

<?php
$xPoint=50;
$Image = imagecreate( 500, 500 );
#1st colour allocated is used for the image background
$backColour = imagecolorallocate( $Image, 250, 250, 90 );
#line colours
$colRed = imagecolorallocate( $Image, 250, 0, 0 );
$colBlue = imagecolorallocate( $Image, 0, 0, 250 );
#draw x & y axis
imageline( $Image, $xPoint, 470, 470, 470, $colBlue );
imageline( $Image, $xPoint, 470, $xPoint, 30, $colBlue );
imagestring( $Image, 3, 250, 475, "samples", $colBlue);
imagestring( $Image, 3, 10, 30, "30'C", $colBlue);
imagestring( $Image, 3, 10, 245, "20'C", $colBlue);
imagestring( $Image, 3, 10, 460, "10'C", $colBlue);
$y1Point=400;
$xinterval=8;
for ( $i = 1; $i <= 50; $i++ ) {
    $xPoint=$xPoint + $xinterval;
    #create dummy data
    $y2Point=rand(100,400);
    imageline( $Image, $xPoint, $y1Point, $xPoint + $xinterval, $y2Point, $colRed );
    $y1Point=$y2Point;
}
header( "Content-type: image/png" );
imagepng( $Image );
imagedestroy( $Image );
?>


For this example, random data is created using the rand() function, with the range of values restricted to 100 - 400. The idea is to plot the first line between data point 1 and 2. The second line is plotted between data point 2 and 3, third line between points 3 and 4, and so on.



The "imagestring" function is used to write text to the graph. The second argument is a font reference (1 is small, 5 is large). The third and forth arguments are the x and y coordinates.

More simple shapes


It turns out that a circle is just an ellipse with a constant radius. So you can draw circles and ellipses with the same method.

#draw a circle
imageellipse($Image, 250, 250, 400, 400, $colRed);
#draw an ellipse
imageellipse($Image, 250, 250, 200, 100, $colBlue);


The second & third arguments are the x & y values for the centre point. The forth & fifth arguments are the width and height of the ellipse.

There is also a method for rectangles, with 4 arguments for two opposing corners (i.e. x1, y1, x2, y2).

#draw a square
imagerectangle($Image, 80, 80, 420, 420, $colBlue);
#draw a rectangle
imagerectangle($Image, 100, 150, 400, 350, $colRed);


After adding these lines of code to my drawtest.php example, the image looks like this:-


You can also use other methods to create colour fills. By using the "imagefilledrectangle" method in the line graph example, the graph area can be seperated from the background.

<?php
$xPoint=50;
$Image = imagecreate( 500, 500 );
#1st colour allocated is used for the image background
$backColour = imagecolorallocate( $Image, 250, 250, 90 );
$graphColour = imagecolorallocate( $Image, 230, 230, 110 );
imagefilledrectangle($Image, $xPoint, 30, 470, 470, $graphColour);

...


So you can see that it is very easy to draw simple shapes with PHP using the GD Library.

Here is a good reference to all GD methods.

Working with existing images


You can also display and manipulate existing images.

Here is an example where two images are displayed together; a jpeg photo and a png copyright notice. Both image files are located in /var/www/images.

<?php
#use existing image
$Image = imagecreatefromjpeg( "images/LongTailedTits2.jpg" );
#load a copyright notice
$Copyright = imagecreatefrompng( "images/copyright.png" );
#get image width & height
$destWidth = imagesx( $Image );
$destHeight = imagesy( $Image );
$srcWidth = imagesx( $Copyright );
$srcHeight = imagesy( $Copyright );
#calculate x & y (position) for copyright
$destX = 0.5 * ($destWidth - $srcWidth);
$destY = 0.9 * ($destHeight - $srcHeight);
imagecopy( $Image, $Copyright, $destX, $destY, 0, 0, $srcWidth,
$srcHeight );
header( "Content-type: image/jpeg" );
imagejpeg( $Image );
imagedestroy( $Image );
imagedestroy( $Copyright );
?>


...and the result looks like this...




No comments:

Post a Comment