Demonstrating designs to clients using PHP's file and image functions

January 23, 2012

Here’s something I picked up from the designers at Catch Digital. When showing site mockups to a client, they would create a directory of images, and build a series of simple HTML pages, each one linking to the next. This allows the clients to click through each mockup and easily see all the designs. The last mockup links back to the directory.

I’ve taken that idea and evolved it with PHP so that the designers don’t need to create the HTML pages - they can just drop images into a directory. The full code is on GitHub, and there’s a demo.

The directory would normally be protected by an .htaccess password, so that only authorised people are able to view the designs. I’ve improved the process by using PHP to loop through the directory and create links for each image.

// build an array of all the image files in the current directory
$directory = opendir("mockups");
$file_types = array('png', 'jpg', 'jpeg', 'gif');
$files = array();
while ($file = readdir($directory)) {
  // Is this one of our accepted file types?
  $extension = substr(strtolower(strrchr($file, '.')), 1);
  if (in_array($extension, $file_types)) {

    // Split the filename so we can check for colours.
    $filename = explode('_', $file);

    if (array_key_exists(2, $filename)) {
      $bk = substr($filename[2], 0, strpos($filename[2], '.'));
    }
    else {
      $bk = FALSE;
    }
    
    $number = $filename[1];

    // If there is no filename[2], remove the file extension.
    if ($dotpos = strpos($number, '.')) {
      $number = substr($number, 0, $dotpos);
    }

    $files[] = array(
      'file' => $file,
      'ext' => $extension,
      'number' => $number,
      'bk' => $bk,
    );
  }
}

sort($files);

For each image, I fetch the background colour of the mockup using the imagecoloratfunction, which is part of the GD library.

  if ($bk) {
    // Is this a valid hex colour?
    if (preg_match('/^([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/i', $bk)) {
      $background = "background: #$bk";
    }
    else {
      // Is there a matching file?
      foreach ($file_types as $file_type) {
        $filename = $bk . '.' . $file_type;
        if (file_exists($filename)) {
          $background = "background: url(bk.jpg) repeat-x;";
          break;
        }
      }
    }
  }
  else {
    // Process the image using GD.
    switch ($extension) {
      case 'png' :
        $im = imagecreatefrompng($img);
        break;
      case 'jpeg':
      case 'jpg' :
        $im = imagecreatefromjpeg($img);
        break;
      case 'gif' :
        $im = imagecreatefromgif($img);
        break;
    }

    // Get the colour of the first pixel of the image.
    $rgb = imagecolorat($im, 1, 1);
    $r = ($rgb >> 16) & 0xFF;
    $g = ($rgb >> 8) & 0xFF;
    $b = $rgb & 0xFF;

    // Set the background colour to match.
    $background = "background-color: rgb($r, $g, $b);";
  }

Then add CSS in the head to set the background colour to match the image file.

body { 
  margin: 0; 
  <?php if($rgb) { print "background-color: rgb($r, $g, $b)"; } ?> 
}