This uses the GD library to create a thumbnail out of an image.
$infile = path to source image
$outfile = file and path to write the thumbnail to
$maxw = Maximum width of the thumbnail
$maxh = Maximum height of the thumbnail
$stretch = Stretch image if it is smaller than the maxw and maxh
The function will preserve the aspect ratio of the image. If you specify 0 for either $maxw or $maxh then the function will assume that the max width/height can be unlimited (ie, if you specify 0 for $maxw it will only resize the height to $maxh likewise for specifying 0 for $maxh)
By default if the source image is already smaller than the thumbnail size it will not be stretched to the $maxw or $maxh. If you specify TRUE for $stretch it will be stretched if it is already smaller than the $maxw and $maxh parameters.
This function supports PNG, JPEG and GIF formats. Adding new formats shouldn't be hard.
<?php
/*
Tye Shavik (tye at tye . ca)
*/
function create_thumbnail($infile,$outfile,$maxw,$maxh,$stretch = FALSE) {
clearstatcache();
if (!is_file($infile)) {
trigger_error("Cannot open file: $infile",E_USER_WARNING);
return FALSE;
}
if (is_file($outfile)) {
trigger_error("Output file already exists: $outfile",E_USER_WARNING);
return FALSE;
}
$functions = array(
'image/png' => 'ImageCreateFromPng',
'image/jpeg' => 'ImageCreateFromJpeg',
);
// Add GIF support if GD was compiled with it
if (function_exists('ImageCreateFromGif')) { $functions['image/gif'] = 'ImageCreateFromGif'; }
$size = getimagesize($infile);
// Check if mime type is listed above
if (!$function = $functions[$size['mime']]) {
trigger_error("MIME Type unsupported: {$size['mime']}",E_USER_WARNING);
return FALSE;
}
// Open source image
if (!$source_img = $function($infile)) {
trigger_error("Unable to open source file: $infile",E_USER_WARNING);
return FALSE;
}
$save_function = "image" . strtolower(substr(strrchr($size['mime'],'/'),1));
// Scale dimensions
list($neww,$newh) = scale_dimensions($size[0],$size[1],$maxw,$maxh,$stretch);
if ($size['mime'] == 'image/png') {
// Check if this PNG image is indexed
$temp_img = imagecreatefrompng($infile);
if (imagecolorstotal($temp_img) != 0) {
// This is an indexed PNG
$indexed_png = TRUE;
} else {
$indexed_png = FALSE;
}
imagedestroy($temp_img);
}
// Create new image resource
if ($size['mime'] == 'image/gif' || ($size['mime'] == 'image/png' && $indexed_png)) {
// Create indexed
$new_img = imagecreate($neww,$newh);
// Copy the palette
imagepalettecopy($new_img,$source_img);
$color_transparent = imagecolortransparent($source_img);
if ($color_transparent >= 0) {
// Copy transparency
imagefill($new_img,0,0,$color_transparent);
imagecolortransparent($new_img, $color_transparent);
}
} else {
$new_img = imagecreatetruecolor($neww,$newh);
}
// Copy and resize image
imagecopyresampled($new_img,$source_img,0,0,0,0,$neww,$newh,$size[0],$size[1]);
// Save output file
if ($save_function == 'imagejpeg') {
// Change the JPEG quality here
if (!$save_function($new_img,$outfile,75)) {
trigger_error("Unable to save output image",E_USER_WARNING);
return FALSE;
}
} else {
if (!$save_function($new_img,$outfile)) {
trigger_error("Unable to save output image",E_USER_WARNING);
return FALSE;
}
}
// Cleanup
imagedestroy($source_img);
imagedestroy($new_img);
return TRUE;
}
// Scales dimensions
function scale_dimensions($w,$h,$maxw,$maxh,$stretch = FALSE) {
if (!$maxw && $maxh) {
// Width is unlimited, scale by width
$newh = $maxh;
if ($h < $maxh && !$stretch) { $newh = $h; }
else { $newh = $maxh; }
$neww = ($w * $newh / $h);
} elseif (!$maxh && $maxw) {
// Scale by height
if ($w < $maxw && !$stretch) { $neww = $w; }
else { $neww = $maxw; }
$newh = ($h * $neww / $w);
} elseif (!$maxw && !$maxh) {
return array($w,$h);
} else {
if ($w / $maxw > $h / $maxh) {
// Scale by height
if ($w < $maxw && !$stretch) { $neww = $w; }
else { $neww = $maxw; }
$newh = ($h * $neww / $w);
} elseif ($w / $maxw <= $h / $maxh) {
// Scale by width
if ($h < $maxh && !$stretch) { $newh = $h; }
else { $newh = $maxh; }
$neww = ($w * $newh / $h);
}
}
return array(round($neww),round($newh));
}
?>
Some hint if you want to use this code for true-color alpha channel transparent images (actually tried it on png-s).
After the
$new_img = imagecreatetruecolor($neww,$newh);
line I added these:
imagealphablending( $new_img, false );
$col = imagecolorallocatealpha( $new_img, 0, 0, 0, 127 );
imagefilledrectangle( $new_img, 0, 0, $neww, $newh, $col );
imagealphablending( $new_img, true );
imageSaveAlpha($new_img, true);
This fills the new image with fully transparent pixels.
The most painful was the last function call, because it took some half an hour to discover that without it the alpha channel isn\'t saved with the image.
I\'ve found a problem with the script (other than this small problem, this script is GREAT!).
I\'ll explain by example:
Is this a bug? Or is this how it is supposed to work?
Here are some changes I made to support GIF transparencies. I also changed the imagecopyresized function to imagecopyresampled because the quality of the shrunk images was fairly poor. This fixed it right up.
// Create new image
if($function == \'ImageCreateFromGif\')
{
$colorTransparent = imagecolortransparent($source_img);
$new_img = imagecreate($neww,$newh);
imagepalettecopy($new_img,$source_img);
imagefill($new_img,0,0,$colorTransparent);
imagecolortransparent($new_img, $colorTransparent);
}
else
{
$new_img = imagecreatetruecolor($neww,$newh);
}
// Copy and resize image
imagecopyresampled($new_img,$source_img,0,0,0,0,$neww,$newh,$size[0],$size[1]);