Image cropping thumbnails

I got some code from someone here before about cropping a thumbnail so it doesn’t distort like when you resize with the wrong proportions.

I never got the code to work though. I can upload the image and it creates a thumbnail, but it doesn’t seem to crop. I want it to crop the thumbnail as a square even if the image is in rectangle format.

Maybe you can see what’s wrong in the following code



//IF FILE IS UPLOADED

if (is_uploaded_file($_FILES['thefile']['tmp_name'])){
	move_uploaded_file($_FILES['thefile']['tmp_name'], $pPath.$_FILES['thefile']['name']) or die ("Couldn¥t copy");


header("Location: ../members.php");

//REMOVES AN OLD FILE IF IT'S THERE BEFORE UPLOADING A NEW ONE
if (($photo_path AND $thumb_path) !=''){

unlink("../$photo_path");
unlink("../$thumb_path");

}



// DEFINE THE FILE
$filename = $pPath.$_FILES['thefile']['name'];
$thumbname = "TN_".$_FILES['thefile']['name'];
$thumbnail = $pPath.$thumbname;


// DETERMINE FILE NAME
$myfilename = substr($filename, 3);
$mythumbname = substr($thumbnail, 3);



    //INSERT QUEARY
$qry = "UPDATE members SET photo_path='$myfilename', thumb_path='$mythumbname' WHERE member_id='$member_id'";
      $result = mysql_query($qry) or die("Query failed"); 




// GET NEW DIMENSIONS

list($width_orig, $height_orig) = getimagesize($filename);



if ($width && ($width_orig < $height_orig)) {

   $per =  (100*$width)/$width_orig;

   $per = round($per);

   $height = ($height_orig*$per)/100;

   echo $height;

   //($height / $height_orig) * $width_orig;

   if ($width < 100){

           $pre = 100 - $width;

        $width = $width + $pre;

        //echo $width;

    }

    if ($width > 100){

        $pre = $width - 100;

        $width = $width - $pre;

        //echo $pre;

    }

} else {

   $height = ($width / $width_orig) * $height_orig;

}



// RESAMPLE

$image_p = imagecreatetruecolor($width, $height);

$image = imagecreatefromjpeg($filename);

imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);



// OUTPUT

imagejpeg($image_p, $pPath.$thumbname, 100);

$pasto = getimagesize($pPath.$thumbname);

link($pPath.$_FILES['thefile']['name']);

//unlink($pPath.$_FILES['thefile']['name']);

$user = 1;

$elwidth = $pasto[0];

$elheight = $pasto[1];


// CROP DIMENSIONS

$width = 100;

$height = 100;

// SET THE PATH TO THE IMAGE TO RESIZE

$input_image = $thumbname;

// GET THE SIZE OF THE ORIGINAL IMAGE INTO AN ARRAY

$size = getimagesize( $input_image );

// PREPARE CANVAS

$canvas = imagecreatetruecolor( $width, $height );

// CREATE A NEW IMAGE IN THE MEMORY FROM THE FILE 

$cropped = imagecreatefromjpeg( $input_image );

// PREPARE IMAGE CROP - CENTER THE CROP OF THE IMAGE

$newwidth = $size[0] / 2;

$newheight = $size[1] / 2;

$cropLeft = ( $newwidth/2 ) - ( $width/2 );

$cropHeight = ( $newheight/2 ) - ( $height/2 );

// GENERATE THE CROPPED IMAGE

imagecopyresized( $canvas, $cropped, 0,0, $cropLeft, $cropHeight, $size[0], $size[1], $newwidth, $newheight );

// SAVE THE CROPPED IMAGE

imagejpeg( $canvas, $mythumbname );

// CLEAR THE MEMORY OF THE TEMP IMAGES

imagedestroy( $canvas );

imagedestroy( $cropped );

}

define $pPath . I think there’s something wrong with your filename.

I forgot to add that code before. It’s the path to the directory where the photos are stored. Here it is:

// Upload File To Web Server
$pPath = “…/photos/”;

In fact, never mind doing that. I know it’s something wrong with your filename.

for some reason the script knocks off the first 3 letters of $myfilename and $mythumbnail, meaning PHP is putting the wrong filepath into it’s SQL table, and is thus unable to find the files

are you calling this script directly, or including it from a directory one level above?

the only include I have is the database connection. Other than that there are no includes

This script is looking for photos 1 directory up and-over.

If you’re running this in /foo/bar/, this script is looking for it’s picture source files in /foo/photos/ … and is depositing the result in /foo/bar/photos/

Yes, the file is not in the root. it’s in a sub directory of the root. so that’s why it’s …/photos/ to go back to the root where the photos folder is

is $width defined before this script begins? There’s a call to it in the first IF statement under ‘GET NEW DIMENSIONS’, but if it’s not defined that call will always be false…

Could be. I’m not sure…I found some other code. I think the photo width and height was there originally to set the width and height of the thumbnail.

// Define the file
$filename = $pPath.$FILES[‘thefile’][‘name’];
$thumbname = "TN
".$_FILES[‘thefile’][‘name’];
$thumbnail = $pPath.$thumbname;

$Photo_Width = “100”;
$Photo_Height = “75”;

// Set a maximum height and width
$width = $Photo_Width;
$height = $Photo_Height;

yeah… those lines need to be in there. Without them the world goes to pot…
Lets see now…
(Follow the bouncing ball, kiddies!) (Seriously. Someone bounce along behind me and make sure i didnt miss something)

If you uploaded a file ‘uploadedphoto.jpg’ which was 50x100
width_orig = 50 and height_orig = 100…
width becomes 10000/50 = 200…
height becomes 200
the script goes and gets …/photos/uploadedphoto.jpg
creates a blank truecolor image canvas at 200x200,
stretches the original image onto the canvas.
outputs the file it just created to …/photos/TN_uploadedphoto.jpg (so now you have a 200x200 thumbnail at maximum quality, when you started with a 50x100…alright…lets see if this makes sense down the road)
We get the image size of the thumbnail we just created (even though we’re already holding them in $width and $height … someone explain that line to me? Is this a test for file-exists?)
We then make an invalid call to link() with only one parameter (or was this a copy/paste error and it was supposed to be unlink? If so, we destroy the original uploaded file.)
We set some more height and width variables with our pasto. Now i’m getting hungry.
We reset width and height to out desired values…
$input_image gets set with the wrong value (it tries to load ‘TN_uploadedphoto.jpg’ rather than ‘…/photos/TN_uploadedphoto.jpg’ )(Should be $pPath.$thumbname) (I think we have found the problem!)
$size fails to be set to its proper values because $input_image does not exist.
…which is just going to cause all manner of errors for the rest of the code.

I changed to this:

$input_image = $pPath.$thumbname;

But the thumbnail doesn’t seem to crop. Or are the settings not set to crop to a square?

So you’re getting a floor(10000/originalwidth) x floor(originalheight*floor(100/originalwidth)) image?
(Honestly, i have no idea where the script gets the idea for this math from)

humor me for a moment and try this:


$pPath = "../photos/";

if (is_uploaded_file($_FILES['thefile']['tmp_name'])){
    move_uploaded_file($_FILES['thefile']['tmp_name'], $pPath.$_FILES['thefile']['name']) or die ("Couldn't copy");
header("Location: ../members.php");

// DEFINE THE CROP SIZE
$width = 100;
$height = 100;

// DEFINE THE FILE
$filename = $pPath.$_FILES['thefile']['name'];
$thumbname = "TN_".$_FILES['thefile']['name'];
$thumbnail = $pPath.$thumbname;

if(file_exists($thumbnail) {
  unlink($thumbnail);
}

$qry = "UPDATE members SET photo_path='$filename', thumb_path='$thumbnail' WHERE member_id='$member_id'";
      $result = mysql_query($qry) or die("Query failed");

list($width_orig, $height_orig) = getimagesize($filename);
$canvas = imagecreatetruecolor( $width, $height );
$cropped = imagecreatefromjpeg( $filename );
$sx = floor($width_orig / 2)-floor($width / 2);
$sy = floor($length_orig / 2)-floor($length / 2);
imagecopyresized( $canvas, $cropped, 0,0, $sx, $sy, $width, $height, $width, $height );
imagejpeg( $canvas, $thumbnail );
imagedestroy( $canvas );
imagedestroy( $cropped );

I tried your example and it got a little closer but some other problems happened instead.

It did crop this time, but it’s cropping the fullsize image and not the thumbnail. Meaning if there is a large image it’s really not much to see on the thumbnail.

Secondly, when I try to remove the photo with my remove photo file(which worked earlier) there is a problem with the path it seems. The weird thing is that the files do not unlink from the directory, but yet you can not see the thumbnail after you have done the remove part either, eventhough the files still seems to be in the directory. So that was ultra weird.

Have any input about this?

Well yes, because i told it to crop the fullsize. What size are you trying to make the thumbnail before cropping it?

Maybe 100px in width for the cropped thumbnail. I don’t really know what that means for the size of the original thumbnail?

… I’m failing to understand.
Are you saying that you want to resize the image to be either 100xsomebiggernumber or somebiggernumberx100, and then crop it to be 100x100?

What I mean is that I want the thumbnail that is cropped to be 100x100. That will be the thumbnail that is to be displayed.

But I don’t know what that means for the uncropped thumbnail in size?

Okay basically you’re asking for 3 images, but not giving enough detail to get what you want.

You have a picture, that is X by Y. That’s the original, untouched picture.
You have a thumbnail, that is R by S, so that you can get as much of the image into the cropped picture, but retaining the proportions of the original.
You want to crop that image so that the third picture is 100x100.

(The math from the original program is starting to make more sense to me now)

So. (X/R = Y/S) AND (R = 100 OR S = 100), depending on which is smaller, R or S.
Alright… so the code now becomes more and more like the original… hopefully with the proper result…i’m going to try taking a shortcut this time, see if i get tripped up.


$pPath = "../photos/";

if (is_uploaded_file($_FILES['thefile']['tmp_name'])){
    move_uploaded_file($_FILES['thefile']['tmp_name'], $pPath.$_FILES['thefile']['name']) or die ("Couldn't copy");
header("Location: ../members.php");

// DEFINE THE CROP SIZE
$width = 100;
$height = 100;

// DEFINE THE FILE
$filename = $pPath.$_FILES['thefile']['name'];
$thumbname = "TN_".$_FILES['thefile']['name'];
$thumbnail = $pPath.$thumbname;

if(file_exists($thumbnail) {
  unlink($thumbnail);
}

$qry = "UPDATE members SET photo_path='$filename', thumb_path='$thumbnail' WHERE member_id='$member_id'";
      $result = mysql_query($qry) or die("Query failed");

list($width_orig, $height_orig) = getimagesize($filename);
if($width_orig > $height_orig) { # Reduce Height to $height, and Width proportionately
   $sy = $height; #S = 100;
   $sx = floor(($sy*$width_orig)/$height_orig); #R = SX/Y
} else { #Reduce Width to $width, and height proportionately
   $sx = $width; #R
   $sy = floor(($sx * $height_orig)/$width_orig) #S = RY/X
}
$canvas = imagecreatetruecolor( $sx,$sy);
$thumb = imagecreatefromjpeg( $filename );
imagecopyresized( $canvas, $thumb, 0,0,0,0, $sx, $sy, $width_orig, $height_orig );
$canvas2 = imagecreatetruecolor( $width, $height );
$sx = floor($sx / 2)-floor($width / 2);
$sy = floor($sy / 2)-floor($height / 2);
imagecopyresized( $canvas2, $canvas, 0,0, $sx, $sy, $width, $height, $width, $height );

imagejpeg( $canvas2, $thumbnail );
imagedestroy( $canvas );
imagedestroy( $canvas2 );
imagedestroy( $thumb );

it gave me a black thumbnail when I uploaded it…do you know why that is?