The html times

Elegantly Powered by Google

Photo Uploader by Thomas Steinmetz November 3rd, 2008 Delicious



Relevant Downloads

Photo Uploader

As with most things that I code, this little photo uploader started with a need from my loving girlfriend. She was on business in India and wanted a way to upload images for her family and friends back home to see (I have changed those directories for this article).

I sat down for a few minutes and made a simple front end page with Lightbox and wrote a quick uploader script. BAM! Done. I emailed her so she could test it out.

While the site did work, it didn't work quite the way she wanted or I intended. She was uploading 3 meg files and there was zero compression... This lead to massive Lightboxes on the screen and insane load times for anyone not on a fiber connection (are there people out there like that these days?). I needed a way to compress the images so that they don't take a century to load, even when there are a few dozen of them on the screen.

Check out the finished example, and read through this tutorial to get a sense of how it works.

The Code

Let's begin by looking at the front end. First thing we'll do is add some php that looks at the url and decides whether our user can upload photos, or just plain look at them:

<?php
  //controls the user -- meesh can uploade, guest can not -- who needs a DB?
  if(isset($_REQUEST['user']))
  {
  if($_REQUEST['user'] == 'meesh')
  {
    $user = 'meesh';
  }
  else
    $user = 'guest';
  }
  else
    $user='guest';
?>

Rather straight forward, right? just some PHP to take care of user permissions ('meesh' was the username I picked for my girlfriend, you can obviously change that to anything you like).

Next, we'll call our CSS and JS, so that we don't end up with a chintzy gallery thats ugly, with now fullscreen previews:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>HTMLTimes Photo Uploader</title>	
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />    
  <link rel="stylesheet" href="css/screen.css" media="screen" />
  <link rel="stylesheet" href="css/lightbox.css" media="screen" />
  <script type="text/javascript" src="js/prototype.js"></script>
  <script type="text/javascript" src="js/scriptaculous.js?load=effects,builder"></script>
  <script type="text/javascript" src="js/lightbox.js"></script>
</head>

<body>
<div id="container">
  <div id="header">
    <div id="header_name">
    	<h1><a href="/photo-uploader" title="">Photos</a></h1>
    </div>
    <span style="margin-left:30px;"><a href="/photo-uploader/?user=<?php echo $user;?>">Random Pics</a> | <a href="/photo-uploader/?user=<?php echo $user;?>&dir=cooper">Cooper Pics</a></span>
  </div>
  
  <div id="content">
    <div id="content_holder">

A simple if statement controls the form with the directory drop-down:

    <?php if($user=='meesh'){?>
    <h2>Photo Uploader 
      <form enctype="multipart/form-data" action="uploader.php" method="post">
        <span>Select Folder:</span>
          <select name="dir">
            <option value="random">Random Pics</option>
            <option value="cooper">Cooper</option>
          </select>
        <input type="file" id='up_photo' name='up_photo' /><input type="submit" value='upload'>
      </form>
    </h2>

The following PHP code opens the directory and pulls out all the files that end in .jpg and .png. You can make use of other image formats too, just look up the PHP functions for the appropriate image type. It then creates the tag for each one. Note that we are using Lightbox to display the images, there is NOT another page for viewing.


    <?php
        }
        /this contorls which directory we open when the user comes to the site
        /if nothing is set in the 'dir' variable, we open the 'random' directory
        f(isset($_REQUEST['dir']))
          $dir = './' .$_REQUEST['dir'];
        else
          $dir = './random';
			

Now we check to see if the $_REQEUST['dir'] variable is populated with a directory. If not, default to the “random” photo directory.

The following PHP code opens the directory and pulls out all the files that end in .jpg and .png. You can make use of other image formats too, just look up the PHP functions for the appropriate image type. It then creates the tag for each one. Note that we are using Lightbox to display the images, there is NOT another page for viewing.

        // open specified directory
        $dirHandle = opendir($dir);
        $count = -1;
        $returnstr = "";
        while ($file = readdir($dirHandle)) {
          // if not a subdirectory and if filename contains the string '.jpg' 
          if(!is_dir($file) && (strpos($file, '.jpg') > 0 or strpos($file, '.png') > 0)) {
          // update count and string of files to be returned
          $count++;
          echo "<a href='$dir/$file' rel='lightbox' title='$file'><img src='$dir/$file'></a>";
         }
        } 
        closedir($dirHandle);
    ?>
    </div>		
  </div>
  <div id="footer">
    <a href="/photo-uploader" title="">Photos</a> --
    <span style="margin-left:5px;"><a href="/photo-uploader/?user=<?php echo $user;?>">Random Pics</a> | <a href="/photo-uploader/?user=<?php echo $user;?>&dir=cooper">Cooper Pics</a></span>
  </div>
</div>
</body>
</html>
			

On to the meat and potatoes of the project, the uploader script:

<?php
  //Temp files of the image
  $uploadedfile 	= $_FILES['up_photo']['tmp_name'];
  $dir 			= $_REQUEST['dir'];
  
  //if it's a png file we are uploading, make a png
  //otherwise make a jpeg
  if(strpos($_FILES['up_photo']['name'], '.png') > 0)
    $src = imagecreatefrompng($uploadedfile);
  else	
    $src = imagecreatefromjpeg($uploadedfile);
  
  //get the original size of the image
  list($width, $height) = getimagesize($uploadedfile);
  
  //Here we make the image 600px wide and make it so that the 
  //height is proportionate to the width 
  $newWidth	= 600;
  $newHeight	= ($height / $width) * 600;
  //this creates the blank X by 600 canvas for our image
  $tmp		= imagecreatetruecolor($newWidth, $newHeight);
  
  //imagecopyresampled() does the hardwork of actually resizing the image for us
  //takes the $src image and copies that into $tmp with the new dimensions
  //visit http://us2.php.net/manual/en/function.imagecopyresampled.php for more info
  imagecopyresampled($tmp, $src, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
  
  //now get the path and the filename -- $dir is the variable for the directory from 
  //the drop-down on the form
  $filename = "./$dir/". $_FILES['up_photo']['name'];
  
  //if you notice, the third argument in imagepng() is '9' and the third in imagejpeg() is '100'
  //this is due to imagepng() has a compression level of 0 to 9 while imagejpg() goes 0 to 100 - php.net for more
  if(strpos($filename, '.png') > 0)
    imagepng($tmp, $filename, 9);
  else
    imagejpeg($tmp, $filename, 100);
  
  //destroy the images now that they have been resized and moved
  imagedestroy($src);
  imagedestroy($tmp); 
  
  //go back to the front end
  header("location:http://htmltimes.com/photo-uploader/?user=meesh&dir=$dir");
?>

The code itself is throroughly commented, but I will go over it briefly.

We get an uploaded image from the user and we need to resize it. Depending on if the image is a .jpg or a .png, we call slightly different functions to do our bidding.

When the final image function is called and the new, resized image has been created, we destroy our temporary images and redirect back to the front end. All this has happened without the user seeing a thing.

Closing Thoughts/Rant:

This script is not meant to be a massive image gallery. It's great for smaller galleries or for times when you do not need a database to control user access. Of course, the username that is allowed to upload could be brute-forced, but if you are worried about that, you should really invest some time and make a secure site, *wink*. Click here to see it in action


Comments

Comments are now closed

Related Articles:

Android Google Phone From T-Mobile

This Month in Tech by Dick Clarke

Dick Clark hasn't put his G1 down for 12 days. Read his review of the first Android phone, from HTC and T-Mobile. Read more …


Information Wants To Be Free

Elegantly Powered by Google