how to dynamically create thumbnails
videos

How to Dynamically Create Thumbnails

In this week’s screencast, I’ll show you how to upload files and then have PHP dynamically create a thumbnail. Whether you’re building an ecommerce site, or just a simple gallery, these techniques will absolutely prove to be useful. If you’re ready for your “spoonfed” screencast of the week, let’s get going!

*Note – There have been a few slight changes to the code after some additional thinking and some great suggestions. Don’t worry, very little has changed. Just some cleanup. You can review the changes below, and/or download the source code.

The Simple Config File

The first step is to create a simple config file where we can store a few variables. By placing these in their own file, we can easily make changes to our code without having to edit many lines.

$final_width_of_image = 100;
$path_to_image_directory = 'images/fullsized/';
$path_to_thumbs_directory = 'images/thumbs/';
  • $final_width_of_image – This variable will store the width of our thumbnail.
  • $path_to_image_directory – This stores the path to our full sized images folder
  • $path_to_thumbs_directory – This stores the path to our full thumbnails directory

Save this file as ‘config.php’ and place it in the root of your folder.

The HTML

Screenshot

Next, create a new page called “index.php” and paste the following.

<?php

require 'config.php';
require 'functions.php';

if(isset($_FILES['fupload'])) {

	if(preg_match('/[.](jpg)|(gif)|(png)$/', $_FILES['fupload']['name'])) {

		$filename = $_FILES['fupload']['name'];
		$source = $_FILES['fupload']['tmp_name'];
		$target = $path_to_image_directory . $filename;

		move_uploaded_file($source, $target);

		createThumbnail($filename);
	}
}
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>

<head>
	<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
	<meta name="author" content="" />
	<title>Dynamic Thumbnails</title>
</head>

<body>
	<h1>Upload A File, Man!</h1>
	<form enctype="multipart/form-data" action="" method="post">
		<input type="file" name="fupload" />
		<input type="submit" value="Go!" />
	</form>
</body>
</html>

First, scroll down a bit to the body tag. To keep things as bare-bones as possible, I’ve created an extremely simple form. But it will get the job done just fine.

<form enctype="multipart/form-data" action="" method="post">
  <input type="file" name="fupload" />
  <input type="submit" value="Go!" />
</form>

Any time that you’re going to be working with the “file upload” input type, you need to add an “enctype” attribute to the form tag.

<form enctype="multipart/form-data"

Rather than posting to a different page, we’ll just write the code in our main document. To do that, we’ll set the action attribute equal to this page.

action="<?php print $_SERVER['PHP_SELF']

Now, scroll back up to the PHP code at the top. We’re requiring two files. The first is the config file that we just created. The second one is “functions.php” – which we’ll create shortly.

Next, we’re checking to see if the page has posted back. If it has, we’ll then check to see if the file that the user chose was either a “jpg”, “gif”, or “png”. We can do this by checking the file name against a regular expression.

if(preg_match('/[.](jpg)|(gif)|(png)$/', $_FILES['fupload']['name']))

To learn more about regular expressions, watch this screencast.

Moving along, we’re creating a few variables.

  • $filename - Stores the name of the file that the user has chosen to upload.
  • $source – When the submit button is clicked, the file will be saved into a temporary directory. This variable will store that path.
  • $target – This will store the path of where the uploaded image should be saved.

Saving the File

The final step is to move the file from the temporary directory into our “images/fullsized” folder. We can do this by calling the move_uploaded_file() function. We’ll pass in two parameters. The first one needs to know the path to the temporary folder. The second needs to know where to save the file. ($source and $target, respectively)

move_uploaded_file($source, $target);

Creating the Thumbnail

Rather than store all of the code in our index.php page, let’s create another page called “functions.php”. Create and open this new file and write a new function called “createThumbnail()”.

function createThumbnail($filename) {

	require 'config.php';

	if(preg_match('/[.](jpg)$/', $filename)) {
		$im = imagecreatefromjpeg($path_to_image_directory . $filename);
	} else if (preg_match('/[.](gif)$/', $filename)) {
		$im = imagecreatefromgif($path_to_image_directory . $filename);
	} else if (preg_match('/[.](png)$/', $filename)) {
		$im = imagecreatefrompng($path_to_image_directory . $filename);
	}

	$ox = imagesx($im);
	$oy = imagesy($im);

	$nx = $final_width_of_image;
	$ny = floor($oy * ($final_width_of_image / $ox));

	$nm = imagecreatetruecolor($nx, $ny);

	imagecopyresized($nm, $im, 0,0,0,0,$nx,$ny,$ox,$oy);

	if(!file_exists($path_to_thumbs_directory)) {
	  if(!mkdir($path_to_thumbs_directory)) {
           die("There was a problem. Please try again!");
	  }
       }

	imagejpeg($nm, $path_to_thumbs_directory . $filename);
	$tn = '<img src="' . $path_to_thumbs_directory . $filename . '" alt="image" />';
	$tn .= '<br />Congratulations. Your file has been successfully uploaded, and a 	  thumbnail has been created.';
	echo $tn;
}

We’ll start by requiring the “config.php” file once again. Next, we’ll check to see whether the user selected a “jpg”, “gif”, or “png”. We must do this because PHP requires a different function depending on the file: “imagecreatefromjpeg”, “imagecreatefromgif”, “imagecreatefrompng”.

imagecreatefromjpeg

After that, we must store the width and height values of the image that the user chose to upload. We can do this by calling “imagesx”, and “imagesy”, respectively.

$ox = imagesx($im);
$oy = imagesy($im);

Next, we’ll create two more variables that will store the width and height values for the thumbnail that will soon be created.

  • $nx – is equal to the value from our config file: 100
  • $ny. We’ll need to run some simple math to find the correction proportionate height.
$nx = $final_width_of_image;
$ny = floor($oy * ($final_width_of_image / $ox));

ImageCreateTrueColor

imageCreateTrueColor

In our case, we’re passing in the “$nx”, and “$ny” variables that we just created.

Image Copy Resized

imagecopyresized
imagecopyresized($nm, $im, 0,0,0,0,$nx,$ny,$ox,$oy);

Saving the Thumbnail

The final steps require that we check to see if a “thumbnails” folder exists. If it doesn’t, we’ll create it by using “mkdir”. Then, we’ll output our new image to the thumbnails folder.

if(!file_exists($path_to_thumbs_directory)) {
  if(!mkdir($path_to_thumbs_directory)) {
      die("There was a problem. Please try again!");
  }
}
imagejpeg.png

Finally, we need to echo out the thumbnail to show the user that his image was uploaded successfully.

$tn = '<img src="' . $path_to_thumbs_directory . $filename . '" alt="image" />';
$tn .= '<br />Congratulations. Your file has been successfully uploaded, and a 	  thumbnail has been created.';
echo $tn;

Finished

Well done! This screencast was somewhat hastily done – because of time constraints. You might want to clean up the code a bit and a bit more error handling.

If you wish to take things further, see if you can figure out how to crop the images as well! As always, I’m more than open to refinement and suggestions!

  • Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.


Add Comment

Discussion 121 Comments

Comment Page 3 of 3 1 2 3
  1. Usman says:

    THANKS A MILLION JEFF!!! I am a beginner anD I realLy appritiate that alot!! I asked every where but no one was able to solve my problem , this tutorial gave me a push once again! and saved my time . Thanks again!
    you just got another fan of ur work! =D
    Cheers
    Usman!!!!

  2. mrsarun says:

    Hey Im getting two warnings, invalid dimensions etc, my image is 1000×663 big.

    Warning: imagecreatetruecolor() [function.imagecreatetruecolor]: Invalid image dimensions in D:\httpd\thalassa\admin\functions.php on line 25

    Warning: imagecopyresized() expects parameter 2 to be resource, boolean given in D:\httpd\thalassa\admin\functions.php on line 27

    function createThumbnail($fileName){

    if(preg_match(‘/[.](jpg)$/’, $fileName)) {
    $im = imagecreatefromjpeg($imagePath . $fileName);
    } else if (preg_match(‘/[.](gif)$/’, $fileName)) {
    $im = imagecreatefromgif($imagePath . $fileName);
    } else if (preg_match(‘/[.](png)$/’, $fileName)) {
    $im = imagecreatefrompng($imagePath . $fileName);
    }

    $ox = imagesx($im);
    $oy = imagesy($im);

    $nx = $finalWidth;
    $ny = floor($oy * ($finalWidth / $ox));

    $nm = imagecreatetruecolor($nx,$ny);

    imagecopyresized($nm, $im, 0, 0, 0, 0, $nx, $ny, $ox, $oy);

    if(!file_exists($thumbPath)) {
    die(“Ett fel uppstod, var god försök igen!”);
    }

    imagejpeg($nm, $thumbPath . $fileName);
    $tn = ”;
    $tn .= ‘Filen har laddats upp och en förhandstitt har skapats!’;
    echo $tn;
    }

  3. Schreyers says:

    Thanks for this, Excellent tutorial

    I did find that i had trouble getting all the variables to go through to the function, so i amended the code to include them.

    createThumbnail($filename,$target,$targetthumbs) etc..

    Thanks again!

  4. Luc says:

    @The use of PHP_SELF: It can be used for XSS attacks, don’t copy that.

    But thanks a Lot for this article anyway, really helped me out at once without any trouble. Usually, even with a good tutorial, you’re trying to get it working for like half an hour. This was copying the part of the code I needed, replacing some variables, testing, making directories I forgot, testing, and it just worked !! :)

  5. pratik says:

    thank you very much !! it helped me lot!!

  6. Mandeep says:

    This is wonderful!!

    Had a question though, how can you change the name so it would include the string “-thumb” before extension or maybe before the file name?

    Sorry I am novice at php, would you use str_replace to achieve this? And if so how would you do it?

  7. Mandeep says:

    Nevermind I figured out how to alter the name of the file and add “-thumb” to it before the extension of the image.

    For anyone interested this is what I have right now, don’t know if it is the optimal way but it is getting the work done so I don’t mind much haha.. anyways here is what I did,

    I just added two more variables, $replace and $replace_with and added them to the image type check like below

    $im = imagecreatefromjpeg($path_to_image_directory . $imgname);
    $replace=’.jpg’;
    $replace_with=’-thumb.jpg’;

    and then used str_replace when the image was saved under thumbs dir like below

    imagejpeg($nm, $path_to_thumbs_directory . str_replace($replace,$replace_with,$imgname));

    so it would check for the extension and replace with “-thumb.ext”, haha. :D

  8. William Rennie says:

    When i click upload, it comes up with image written on the page, and says it was successfully done, when i looked i couldnt find the image in the folders. Help please Jeff? Lol.

  9. Mandeep Patel says:

    @William

    Do you have the correct permissions to for the directory where the image is gone? Is it writable? I had a similar problem and for me the directory was not writable causing the same thing which was I would just get “image” as a word and not the thumbnail. So try to make sure the directory where the image is going is writable. :)

  10. sajuuu says:

    Hi mate,

    beautiful tutorial mate, i have implemented this and it works PERFECT…. BUT i have a question for u, i want to give the admin the choice to upload two images… with your tutorial I’ve managed to do 1 image upload, how would i do another get the 2nd browse image button to simply save the full size image into the same folder as the 1st image with out making a Thumbnail for the 2nd image…?

    i hope that doesn’t sound confusing.

    Thank u in advance

    Regards

    Sajuuu

  11. sajuuu says:

    mate its alright i done it… sorry should have tried it 1st, before i posted on here…

    Thanks for this tutorial neway

    Regards

    Sajuuu

  12. It would have been nice to have some cropping options like “crop from center” etc.

  13. karthi says:

    Hello use this

    its so simple,if u have any queries mail at karthid@in.com

    $ffmpeg = “ffmpeg Installed path”

    $flvfile = “source video file with root path”

    $png_path ” “Destination video file with root path and file type”

    exec(“$ffmpeg -y -i $flvfile -vframes 1 -ss 00:01:60 -an -vcodec png -f rawvideo -s 110×90 $png_path”);

    all the best….

  14. sleg says:

    Very useful,

    Thanks a lot Jeffrey!.

  15. Trev says:

    Hey man thanks for this tut would be very handy on my site
    but im getting this error on localhost
    any help would be great
    cheers mate

    Access forbidden!

    You don’t have permission to access the requested object. It is either read-protected or not readable by the server.

    If you think this is a server error, please contact the webmaster.

    Error 403

    localhost
    23/09/2011 23:36:47
    Apache/2.2.14 (Win32) DAV/2 mod_ssl/2.2.14 OpenSSL/0.9.8l mod_autoindex_color PHP/5.3.1 mod_apreq2-20090110/2.7.1 mod_perl/2.0.4 Perl/v5.10.1

  16. Vojta says:

    Hi! Thanks for the tutorial, it’s rly helpfull.
    I have one more question – always when I trying resize some image, which is not 2 times bigger than thumb size, the result is not so good quality. I know, that the imagejpeg() have a quality parameter, however when it is set to 100, the thumbs are still bad quality:(
    Any idea to fix the quality when I trying resize an image which is not 2 times bigger than thumb? thx

  17. nimr0d says:

    Dude… clean, simple, easy to follow(if you hit pause once in a while) and awesome :P

    Great tutorial! Never knew it could be so easy, kinda been avoiding this subject cus i thought there’d be a million advanced things, but you made it simple :)

    thx for a great tut

Comment Page 3 of 3 1 2 3

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.