Tutorial: Introduction to Images (Registration Img Auth Tut)
Images with PHP can be daunting at first - Look at the manual; theres a TON of functions. Where to start?
It's actually very easy. The first thing to do is to check if you have gd and if you CAN create images.
Run this script:
PHP:
<?php
imagecreate(1,1);
?>
If you get fatal errors, it doesn't work. Obviously. If it isn't working you need to check your gd extension, make sure its loaded. PHP's phpinfo() function may be helpful here. I was able to install it on PHP5 in all of 5 seconds; I haven't been able to get it with PHP4. Someone who knows more about configuring servers then I do can probally do it, but this tutorial WILL work for PHP4 if gd is enabled on your server.
The hardest part of using images is knowing what functions to use. The PHP manual (link) will come in handy.
In this tutorial, were going to do a case study on how to make those anti-robotic registration forums are using these days. If your not familiar, its a image with a randomly generated string inside it.
Lets get to it then!
First, we need to define some constants that we'll use during the script. We define them as constants so we can easily modfiy at a later time without changing the actual script - this is good coding practice and has many uses.
PHP:<?php
define('X_SIZE', 125);
define('Y_SIZE', 50);
define('BORDER_THICKNESS', 5);
define('FONT', 'arialbd.ttf');
define('FONTSIZE', 15);
define('LEGNTH', 8);
?>
-
[*]X_SIZE is going to be the horizontel length of our image in pixels.
[*]Y_SIZE is going to be the vertical length of our image in pixels.
[*]BORDER_THICKNESS is going to be the thickness of the "frame" of our image in pixels. For those of you that care about boxmodels, the frame is put on the INSIDE of the box defined by X and Y sizes, not the outside.
[*]FONT is the path and filename of the font we'll use. I stuck 'arialbd.ttf' (arial bold) in the same directory as my script, but you could have it anywhere. Make sure the path is correct! (Examples = 'D:\fonts\arialbd.ttf', 'misc/fonts/arialbd.ttf').
[*]FONTSIZE is the size of our font!
[*]LEGNTH is the legnth of our random string in characters.
If you change these values, it may take expirementation to make sure everything fits.
The next step is to create a image, although realisticly its like making a new canvas in photoshop. PHP function imagecreate takes 2 arguments - the first one is X-Axis size and the second one Y-Axis. We'll use this:
PHP:<?php
$image = imagecreate(X_SIZE,Y_SIZE) or die ('Cannot Initialize new GD image stream');
?>
Now we need to let PHP know what colors we'll be using. You'll need to know the Red, Green, and Blue values for each color we'll use. Photoshop does this quite nicely, and this is a online sheet (link)
The first color we allocate (let PHP know about) will be set as the image background color and any colors after have no special importance.
Nows as good as time as any to tell the theory of how I will be making the frame. Theres no frame() command, I'm afraid. Say you a 4'x4' piece of red plywood, and on top of that, in the middle, you put a 2'x2' piece of brown plywood. Now, the brown plywood has a 1' red border around it . Thats how were going to make our border/frame - put a smaller box (colored our desired BG) on top of the bigger bpx (colored border color).
Back to the colors, we'll use a function called imageColorAllocate. It takes 4 arguments - image handle, red, green, blue.
PHP:<?php
$grey = imageColorAllocate($image,170,170,170); # background - its actually going to be our border!
$lightBlue = imageColorAllocate($image,102,153,255); # this will be our real background
$black = imageColorAllocate($image,0,0,0); # text color
?>
Now lets make our border. We'll draw a rectangle on top of our grey colored image. We use this function - imageFilledRectangle. It takes these arguments - image handle, start X position, start Y position, end X pos, end Y pos, color.
Assuming border thickness of x we should start it x pixels away from the top and x pixels away from the left. That indicates our first x/y arguments will be x. The end positions our reverse that - kind of. The code explains better then words, IMO.
PHP:<?php
imageFilledRectangle($image, BORDER_THICKNESS, BORDER_THICKNESS, (X_SIZE-BORDER_THICKNESS), (Y_SIZE-BORDER_THICKNESS), $lightBlue);
?>
Well, now we need our random string. The code we'll use for this gets a random number (note that the high integer I used in rand() is NOT a random number; its the highest some operating systems can go (see php.net comments)) and divides the current time by the number we just generated. We then MD5 it to get a mix of letters and numbers and finish off by using substr to get it to the desired legnth.
PHP:<?php
$word = substr(md5((time()/rand(1,2147483647))), 0, LEGNTH);
?>
Now, to make it easier on visitors that get confused by 'o's and zeros, we'll make everything capitalized and replace all 'o's with 0s. Then you can just note to the user that there are no 'o's; only zeros.
PHP:<?php
$w = str_replace('O', 0, strtoupper($word));
?>
Now, we want to put our random string in the middle of our image. I stole this from php.net; no need to reinvent the wheel. It does some simple arithmetic with the image size and the legnth of the string (in pixels - takes into account the font and fontsize) and decides where we should start putting the text.
PHP:<?php
$text_bbox = ImageTTFBBox(FONTSIZE, 0, FONT, $w);
$text_pos_x = (X_SIZE - ($text_bbox[2] - $text_bbox[0])) / 2;
$text_pos_y = (Y_SIZE - ($text_bbox[1] - $text_bbox[7])) / 2;
$text_pos_y -= $text_bbox[7];
?>
Now, lets actually add the text to the image. We'll use the function imageTTFText which takes these arguments: image handle, font size, angle of rotation (0 for normal ltr text), start position x-axis, start position y-axis, color (which you allocated to a var), font, and text. Remember that we previous got our start positions into $text_pos_x and $text_pos_y.
PHP:<?php
imageTTFText($image, FONTSIZE, 0, $text_pos_x, $text_pos_y, $black, FONT, $w);
?>
Now lets actually send the image to the browser:
PHP:<?php
imagePNG($image);
?>
Note that if you wanted to save the image (although it wont show it) you could do something like
PHP:<?php
imagePNG($image, 'randImage'.$w.'.png');
?>
That will save it as randImageRANDOMSTRINGHERE.png in the same directory as the script.
Now lets free up the memory from creating this operation.
PHP:<?php
imageDestroy($image);
?>
Our final script may look like this:
PHP:
<?php
define('X_SIZE', 125);
define('Y_SIZE', 50);
define('BORDER_THICKNESS', 5);
define('FONT', 'arialbd.ttf');
define('FONTSIZE', 15);
define('LEGNTH', 8);
# let the browser know its getting a image, not a text file or something
header("Content-type: image/png");
# lets make the image
# First Argument is X Axis, Second is Y
$image = imagecreate(X_SIZE,Y_SIZE) or die ('Cannot Initialize new GD image stream');
# now we have to specify the colors we'll use
# the first color is background color (automatically)
$grey = imageColorAllocate($image,170,170,170); # background - its actually going to be our border!
$lightBlue = imageColorAllocate($image,102,153,255);
$black = imageColorAllocate($image,0,0,0);
# int ImageFilledRectangle (int im, int x1, int y1, int x2, int y2, int col)
imageFilledRectangle($image, BORDER_THICKNESS, BORDER_THICKNESS, (X_SIZE-BORDER_THICKNESS), (Y_SIZE-BORDER_THICKNESS), $lightBlue);
# word
$word = substr(md5((time()/rand(1,2147483647))), 0, LEGNTH);
# thats nice, but people get confused with 0 and O and o so0O
$w = str_replace('O', 0, strtoupper($word));
# Now this is a bit of code I stole from the PHP manual, but it works
$text_bbox = ImageTTFBBox(FONTSIZE, 0, FONT, $w);
$text_pos_x = (X_SIZE - ($text_bbox[2] - $text_bbox[0])) / 2;
$text_pos_y = (Y_SIZE - ($text_bbox[1] - $text_bbox[7])) / 2;
$text_pos_y -= $text_bbox[7];
# ImageTTFText (int im, int size, int angle, int x, int y, int col, string fontfile, string text)
imageTTFText($image, FONTSIZE, 0, $text_pos_x, $text_pos_y, $black, FONT, $w);
# send the image
imagePNG($image);
# free memory
imageDestroy($image);
?>
And we could use it like
Code:
<html>
<head>
<title> random words on image </title>
</head>
<body>
<img src="SCRIPT.php" />
<p> All 'O's and zeros are ZEROS. All leters are capitalized.</p>
</body>
</html>
One more note - if your trying to steal fonts out of your system-fonts category, I had to go to edit->copy, not right-click. ALso, if the fotns were outside of my system font dir, they were invisible no matter what, but they were still where I pasted them to (i could check by pasting again and getting 'Do you want to overwrite me?')
Thats it folks.
Read the stickies or die.
___________________
http://www.philbrodeur.com - Expert PHP Development and Tutorials



