PHP
  Home arrow PHP arrow Page 2 - Security Images with PHP and ImageMagi...
Dev Shed Forums 
Administration  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Forums Sitemap 
IBM® developerWorks 
Dedicated Servers 
E-Commerce Hosting 
Linux Web Hosting 
Managed Hosting 
Small Business Hosting 
Download TestComplete 
VPS Hosting 
Weekly Newsletter

 
Developer Updates  
Free Website Content 
IBM Rational Software Development Conference
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
PHP

Security Images with PHP and ImageMagick
By: David Fells
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 41
    2004-10-05

    Table of Contents:
  • Security Images with PHP and ImageMagick
  • The Image Generator
  • The Form
  • Conclusion

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
     
    ADVERTISEMENT

    PCmover - $15 Off with Coupon Code CJPH7Q

    Security Images with PHP and ImageMagick - The Image Generator
    (Page 2 of 4 )

    First, let me quickly go over the files and directories involved with our little application. They are available in the support files for this article.

    /arial.ttf
    /securityimage.php
    /signupdemo.php
    /images/bg1.png
    /images/bg2.png
    /images/bg3.png
    /images/tmp/ (chmod to 777)

    We will use Arial as our font of choice in this article, and we will use the three background images from the original article. Take note of the /images/tmp/ directory. This is where our random images will be stored. Since we are not creating and manipulating an image in memory as we would be with GD through a PHP script, we have to save out an actual copy of our generated security image, and the tmp directory is where they'll go.

    Let's have a look at the first portion of our securityimage.php script:

    <?php
    ob_start();
    session_start();

    $bgdir = 'images/';
    $bgs = array('bg1.png', 'bg2.png', 'bg3.png');
    $im = $bgdir.$bgs[rand(0, count($bgs)-1)];

    I typically use output buffering in all my scripts to avoid random problems regarding setting cookies or session variables after outputting to the browser, so we begin with ob_start(), then of course session_start() to initiate our session. The next bit of code simply selects a random background image. We simply pick a random image from an array of predefined images and store the value. The images could also be kept track of in a database or we could manually browse the directory on each run and grab an image, but realistically you will not need more than a few backgrounds, so I think this approach is fine.

    Next:

    $chars = array('a','A','b','B','c','C','d','D','e','E','f','F','g','G',

    'h','H','i','I','j','J',
          'k','K','l','L','m','M','n','N','o','O','p','P','q','Q','r',

    'R','s','S','t','T',
          'u','U','v','V','w','W','x','X','y','Y','z','Z','1','2','3',

    '4','5','6','7','8','9');

    $textstr = '';
    for ($i = 0, $length = 8; $i < $length; $i++) {
       $textstr .= $chars[rand(0, count($chars) - 1)];
    }

    $hashtext = md5($textstr);
    $tmpname = $hashtext.'.png';
    $_SESSION['strSec'] = $hashtext;

    First off we define the characters that we want to use in our random string, then we go through a for loop of eight iterations, each time adding one random character from our array to our random string variable. Once that is done, we hash the text with md5() and store it in a session variable. We will use this session variable to check that the user enters the correct value in the signup form. We also define $tmpname which will house the name of the image we will create in the tmp directory.

    $font = 'arial.ttf';
    $size = rand(24, 36);
    $hexValues = array('0','1','2','3','4');
    $numHex = count($hexValues);
    $color = '';
    for ($i = 0; $i < 6; $i++) {
     $color .= $hexValues[rand(0, $numHex-1)];
    }
    $gravities = array('West', 'Center', 'East');
    $gravity = $gravities[rand(0, count($gravities)-1)];

    $angle = rand(-5, 5);

    This chunk of code decides how our text will look. First we pick a font (remember, you can use any font you like, but different fonts have different sizes and kerning so they will require experimentation to achieve proper positioning), then we generate a random hex color using only 0, 1, 2, 3 and 4 as possible values to ensure that our color is dark enough to be visible on our background. Next we define the gravities that we want to use.

    Gravity in ImageMagick allows us to decide how we want primitives (simple shapes and text) to gravitate in our image. I chose to use the gravities that would cause the fewest problems getting text to appear without clipping.

    After that we randomly select a gravity then we randomly select an angle between -5 and 5 degrees. Something important to note here is that our angle will actually tilt the whole image, background and all, not just the text. While we could achieve tilting just the text, it would require multiple ImageMagick commands as well as multiple temporary images and some image compositing. Tilting the image as a whole still gives us the randomness that we need to avoid screen scrapers, and that's what matters.

    $cmd  = '/usr/bin/convert';
    $cmd .= ' -font "'.$font.'"';
    $cmd .= ' -fill "#'.$color.'"';
    $cmd .= ' -pointsize '.$size;
    $cmd .= ' -gravity "'.$gravity.'"';
    $cmd .= ' -draw \'text 0,0 "'.$textstr.'"\'';
    $cmd .= ' -rotate '.$angle;
    $cmd .= ' ./'.$im.' ./images/tmp/'.$tmpname;

    exec($cmd);

    This bit of code is where we actually prepare the ImageMagick command using the convert utility. I have broken up the switches by line for readability. You may have to change the path to convert depending on your system (using `which convert` from a shell will tell you where it's at).

    The first line is where we set our font with the -font switch. The next line is where we define our fill color. If you are familiar with drawing tools like Photoshop or Flash, you will know that fill applies to anything drawn on your canvas using tools that work with your fill color. Line three defines the size of the text in points (72 points per inch in typography but it can vary on computers) with the -pointsize option.

    Next we define gravity with the -gravity switch. This ensures that our text will align left, right, or center using the $gravity variable defined above. The next line, -draw, is the meat of our call to convert. Draw allows us to create primitives such as circles, squares, and in this case text. The keyword "text" lets draw know that we will be drawing a text primitive.

    Following this are the x,y coordinates to use when drawing our text. Since we are using gravity for positioning, these are left at 0,0. After that we simply plug in our random text from above to complete the -draw option. The following line tells convert to rotate our image by our randomly chosen angle, and the last line specifies our randomly chosen background image as the source and the name we chose as a temporary file in the tmp directory as the target. This is topped off with a call to exec() to run the command.

    header('Content-Type: image/png');
    print fread(fopen('./images/tmp/'.$tmpname, 'r'), filesize('./images/tmp/'.$tmpname));

    exec('rm -f ./images/tmp/'.$tmpname);

    ob_end_flush();

    The last portion of the securityimage.php script is what actually sends the image back to the browser. We first send an HTTP Content-Type header, then we echo the contents of our temporary image file. After we have read and outputted the image, we have no more use for the file itself, so we delete it with a command line call. This keeps our temp directory nice and neat. Lastly, we call ob_end_flush(); to send our data to the browser.

    More PHP Articles
    More By David Fells


       · In your $cmd commands, the -draw line is incorrect, or wouldn't work for me. If you...
       · hi,i copy and paste the code same as given in site..but dont know ..it doesnt...
     

       

    PHP ARTICLES

    - Setting Up a Web-based Image Hosting Service
    - Comparing Files and Databases with PHP Bench...
    - Setting Up a Web-Based Image Gallery
    - Using Timers to Benchmark PHP Applications
    - Benchmarking Applications with PHP
    - Setting Up a Web-Based File Manager: PHPfile...
    - Developing a Modular Class For a PHP File Up...
    - Setting Up a Web-Based File Manager: bfExplo...
    - Defining a Custom Function for File Uploader...
    - Parsing Child Nodes with the DOM XML extensi...
    - Creating an Error Handling Module for a PHP ...
    - Accessing Attributes and Cloning Nodes with ...
    - Retrieving Information on Selected Files wit...
    - Handling HTML Strings and Files with the DOM...
    - Building File Uploaders with PHP 5

     
    Accelerating Trading Partner Performance
     
    Competing on Analytics
     
    Cost Effective Scaling with Virtualization and Coyote Point Systems
     
    Five Checkpoints to Implementing IP Telephony
     
    Hosted Email Security: Staying Ahead of New Threats
     




    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 3 hosted by Hostway