| abstract |
 |
Built-in PHP library gd does not have ready-to-use function for photo(jpeg) thumbnail generation. Although there are many such examples on the net, they are usually not suitable for effective generating series of thumbnails (240x240, 140x140, 80x80). This article provides php function thumbnail_generator and trivial image uploading script, which generates series of thumbnails.
| compatible |
 |
PHP 4.1.0 or higherPHP 5
thumbnail_generator() function uses proportion-correct scaling: it scales longest side of image to specified value. Following function, thumbnail_calcsize calculates resized width and height (returned as list):
<?php
function thumbnail_calcsize($w, $h, $square)
{
$k = $square / max($w, $h);
return array($w*$k, $h*$k);
}
?>
thumbnail_generator() function uses two arguments: $srcfile - source jpg file name, and $params array.
$params is a two dimensional array: first dimension (0..n) specifies parameters for each thumbnail, second dimension (string hash)
specifies destination file name (key 'file') and thumbnail size (key 'size'). See code:
<?php
$params = array(array('size' => 200, // first thumbnail, should fit in square 200x200
'file' => 'thumbnail200.jpg'), // output file thumbnail200.jpg
array('size' => 100, // second thumbnail, should fit in square 100x100
'file' => 'thumbnail100.jpg'), // output file thumbnail100.jpg
array('size' => 50, // etc...
'file' => 'thumbnail50.jpg'));
// calling thumbnail_generator
thumbnail_generator("source.jpg", $params);
?>
You should specify largest thumbnail first, as thumbnail_generator will use largest thumbnail result to generate all other.
Here is the code:
<?php
// don't forget to insert thumbnail_calcsize function (see above)
function thumbnail_generator($srcfile, &$params)
{
// getting source image size
@list($w, $h) = getimagesize($srcfile);
if ($w == false)
return false;
// checking params array
if (!(is_array($params)&&is_array($params[0])))
return false;
$src = ImageCreateFromJpeg($srcfile);
list($s1_w, $s1_h) = thumbnail_calcsize($w, $h, $params[0]['size']);
// Create first thumbnail
// Remember, first thumbnail should be largest thumbnail
$img_s1 = imagecreatetruecolor($s1_w, $s1_h);
imagecopyresampled($img_s1, $src, 0, 0, 0, 0, $s1_w, $s1_h, $w, $h);
imagedestroy($src); // Destroy source image
// Other thumbnails are just downscaled copies of the first one
for($i=1; $i<sizeof($params); $i++)
{
list($cur_w, $cur_h) = thumbnail_calcsize($w, $h, $params[$i]['size']);
$img_cur = imagecreatetruecolor($cur_w, $cur_h);
imagecopyresampled($img_cur, $img_s1, 0, 0, 0, 0, $cur_w, $cur_h, $s1_w, $s1_h);
imagejpeg($img_cur, $params[$i]['file'], 90);
imagedestroy($img_cur);
}
// Saving first thumbnail
imagejpeg($img_s1, $params[0]['file'], 90);
imagedestroy($img_s1);
return true;
}
?>
This function is up to 4x faster comparing to subsequent loading and downscaling of the same jpeg file to different resolutions.
Here is a trivial photo-uploading script, which allows user to upload photo, stores it and
generates three thumbnails (240x240, 140x140, 80x80).
This script has three notable code branches:
- Photo uploading form -- shown when user simply accesses the page
- Upload processing -- executed when POST query is received and file was selected
- Upload result -- shown after upload processing, when file GET parameter is added
<?php
// Don't forget to change next two variables
// Or create web-server writable directory aeupload in
// the directory with this php file
$upload_dir = "aeupload"; // Directory for file storing
// filesystem path
$web_upload_dir = "aeupload"; // Directory for file storing
// web-server dir
/* upload_dir is filesystem path, something like
/var/www/htdocs/files/upload or c:/www/files/upload
web upload dir, is the webserver path of the same
directory. If your upload-directory accessible under
www.your-domain.com/files/upload/, then
web_upload_dir is /files/upload
*/
// testing upload dir
// remove these lines if you're sure
// that your upload dir is really writable to PHP scripts
$tf = $upload_dir.'/'.md5(rand()).".test";
$f = @fopen($tf, "w");
if ($f == false)
die("Fatal error! {$upload_dir} is not writable. Set 'chmod 777 {$upload_dir}'
or something like this");
fclose($f);
unlink($tf);
// end upload dir testing
// * * * * *
// INSERT SOURCE CODE OF thumbnail_calcsize() AND thumbnail_generator() HERE
// * * * * *
// Upload processing part:
if (isset($_FILES['file']) && ($_FILES['file']['size'] > 0))
{
$u_filename = basename($_FILES['file']['name']);
move_uploaded_file($_FILES['file']['tmp_name'], $upload_dir.'/'.$u_filename);
// Setting params array for thumbnail_generator
$params = array(array('size' => 220,
'file' => $upload_dir.'/s1-'.$u_filename),
array('size' => 140,
'file' => $upload_dir.'/s2-'.$u_filename),
array('size' => 80,
'file' => $upload_dir.'/s3-'.$u_filename));
if (thumbnail_generator($upload_dir.'/'.$u_filename, $params) == false)
die("Error processing uploaded file {$u_filename}");
// ok, redirecting
// same host (HTTP_HOST), same script (PHP_SELF)
// add ?file=filename parameter
header("Location: http://{$_SERVER['HTTP_HOST']}{$PHP_SELF}?file={$u_filename}");
exit();
}
// Upload processing end
?>
<html><head>
<title>PHP multiple thumbnail generator</title>
</head><body>
<?php
if (!isset($_GET['file'])) {
// Following HTML code is outputed when user just loads this page
?>
<h1>Upload image:</h1>
<form action="<?php echo $PHP_SELF; ?>" method="post" enctype="multipart/form-data">
<script type="text/javascript">
/* This function is called when user selects file in file dialog */
function checkext(upload_field)
{
// this is just an example of checking
// image file extension - jpg/jpeg
var re_text = /\.jpeg|\.jpg/i;
var filename = upload_field.value;
/* Checking file type */
if (filename.search(re_text) == -1)
{
alert("Please select JPEG file");
upload_field.value = '';
}
return true;
}
</script>
Select jpeg photo:
<input type="file" name="file" id="file" onChange="return checkext(this)">
<br><br>
<input type="submit" value="upload & generate thumbnails">
</form>
<?php
}
else {
// And this HTML code is shown when image was uploaded
$file = $_GET['file'];
?>
<h1>Photo: <?php echo $file; ?></h1>
<div align="center">
<!-- Outputting thumbnails -->
<img src="<?php echo $web_upload_dir.'/s1-'.$file; ?>">
<img src="<?php echo $web_upload_dir.'/s2-'.$file; ?>">
<img src="<?php echo $web_upload_dir.'/s3-'.$file; ?>">
<br><br>
<!-- Outputting uploaded photo -->
<img src="<?php echo $web_upload_dir.'/'.$file; ?>">
</div>
<?php
}
?>
<br><br><br>
Example by <a href="http://www.anyexample.com/">AnyExample</a>
</body>
</html>
?>
| warning |
 |
By default, PHP does not allow uploading files larger than 2Mb. Uploading of large photos will fail if you will
not change upload-max-filesize and
post-max-size directives.Don't forget to use enctype="multipart/form-data" in upload form tagProtect your photo-uploading script with some type of authentication or captcha-checking method.
| tested |
 |
FreeBSD 6.2 :: PHP 5.2.1RHEL 5.0 :: PHP 4.4.5