tags:

views:

522

answers:

6

Well 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);
A: 

Have a look at this upload class. It does what you want and a lot more besides.

da5id
Don't want to do a lot more, want to do what I asked without extra overhead
Andrew G. Johnson
+2  A: 

You'll need to calculate the new width & height to keep the image proportionat. Check out example 2 on this page:

http://us3.php.net/imagecopyresampled

Kevin Tighe
Great! Researched the function and got what I wanted, I'll post the source in a bit
Andrew G. Johnson
+1  A: 

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);
Andrew G. Johnson
A: 

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.

Alnitak
A: 

Imagick (aka Image Magic) replaced GD a long time ago, and it's very simple, clean and OO styled (but you don't need your code to be OO to use it).

Here's a great blog on using Imagick because the PHP documentation is borderline useless: http://valokuva.org/?cat=1

TravisO
Especially http://valokuva.org/?p=92
Adriano Varoli Piazza
What makes imagick better other than your claims of simpleness and cleanliness
Andrew G. Johnson
A: 

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);
        }
    }
Derrick