Having issues with GD thumbnail generator
Question
I'm using PHP to generate thumbnails. The problem is that I have a set width and height the thumbnails need to be and often times the images are stretched.
What I'd like is the image to remain at the same proportions and just have black filler (or any color) either on the left & right for tall images or top & bottom for wide images.
Here is the code I'm currently using: (dumbed down a bit for readability)
$temp_image_file = imagecreatefromjpeg("http://www.example.com/image.jpg");
list($width,$height) = getimagesize("http://www.example.com/image.jpg");
$image_file = imagecreatetruecolor(166,103);
imagecopyresampled($image_file,$temp_image_file,0,0,0,0,166,103,$width,$height);
imagejpeg($image_file,"thumbnails/thumbnail.jpg",50);
imagedestroy($temp_image_file);
imagedestroy($image_file);
Solution
You'll need to calculate the new width & height to keep the image proportionat. Check out example 2 on this page:
OTHER TIPS
Okay got it working, here's what I ended up doing:
$filename = "http://www.example.com/image.jpg";
list($width,$height) = getimagesize($filename);
$width_ratio = 166 / $width;
if ($height * $width_ratio <= 103)
{
$adjusted_width = 166;
$adjusted_height = $height * $width_ratio;
}
else
{
$height_ratio = 103 / $height;
$adjusted_width = $width * $height_ratio;
$adjusted_height = 103;
}
$image_p = imagecreatetruecolor(166,103);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p,$image,ceil((166 - $adjusted_width) / 2),ceil((103 - $adjusted_height) / 2),0,0,ceil($adjusted_width),ceil($adjusted_height),$width,$height);
imagejpeg($image_p,"thumbnails/thumbnail.jpg",50);
Here's a function I wrote that takes a GD image object, max width, max height, and rescales within those parameters:
function resized($im, $mx, $my) {
$x = $nx = imagesx($im);
$y = $ny = imagesy($im);
$ar = $x / $y;
while ($nx > $mx || $ny > $my) {
if ($nx > $mx) {
$nx = $mx;
$ny = $nx / $ar;
}
if ($ny > $my) {
$ny = $my;
$nx = $ny * $ar;
}
}
if ($nx != $x) {
$im2 = imagecreatetruecolor($nx, $ny);
imagecopyresampled($im2, $im, 0, 0, 0, 0, $nx, $ny, $x, $y);
return $im2;
} else {
return $im;
}
}
If the resulting image doesn't need rescaling then it just returns the original image.
Have a look at this upload class. It does what you want and a lot more besides.
This rescales the image to the larger size of the width and height and then crops it to the correct size.
// Crete an image forced to width and height
function createFixedImage($img, $id=0, $preFix=false, $mw='100', $mh='100', $quality=90){
// Fix path
$filename = '../'.$img;
// Check for file
if(file_exists($filename))
{
// Set a maximum height and width
$width = $mw;
$height = $mh;
// Get new dimensions
list($width_orig, $height_orig) = getimagesize($filename);
$ratio_orig = $width_orig/$height_orig;
if ($width/$height < $ratio_orig) {
$width = $height*$ratio_orig;
}else{
$height = $width/$ratio_orig;
}
// Resample
$image_p = imagecreatetruecolor($mw, $mh);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
// Output
imagejpeg($image_p, "../images/stories/catalog/{$preFix}{$id}.jpg", $quality);
}
}