Skip to content
Advertisement

Crop Uploaded Image To 1:1 Ratio PHP

I have my own PHP function allowing users to update their profile image.

It all works fine, however, I am having a problem where users can upload any size image they want; i.e: 564 x 346.

I do not want this to happen. I would like the image that they select to upload to be cropped to a 1:1 ratio and centred; i.e: it goes from 564 x 346 to 346 x 346 and centres to the middle of the image.

None of the scripts that I have found seem to work for my site (at least the way I want them to).

This is the code I am currently using to update their avatar. It consists of checking if they have a correct file extension & if the image is less than 256kb in size:

    $ext = array('jpg', 'jpeg', 'png');
    $file       = $_FILES['avatar']['name'];
    $fileext    = strtolower(end(explode('.', $file)));
    $filetmp    = $_FILES['avatar']['tmp_name'];

    if(!in_array($fileext, $ext)){
        $errors[] = 'Please select a valid file type. (JPG, JPEG or PNG)';  }
    if($_FILES['avatar']['size'] > 256000){
        $errors[] = 'Avatars cannot exceed a 256kb file size.';
    }

    if(empty($errors)){
        updateAvatar($conn, $username, $filetmp, $fileext);
    } else if(!empty($errors)){
        echo output_errors($errors);
    }
    if(isset($_SESSION['updateAvat'])){
        flash('You have successfully updated your avatar.');
        unset($_SESSION['updateAvat']);
    }

This is the updateAvatar() function that I have made and is called on line 13:

function updateAvatar($conn, $username, $filetmp, $fileext){
    $file = md5(microtime() . $filetmp) . '.' . $fileext;
    $filepth = './data/user_data/img/udid/prof/' . $file;
    move_uploaded_file($filetmp, $filepth);
    if(mysqli_query($conn, "UPDATE users SET profile = '$file' WHERE username = '$username'")){
        $_SESSION['updateAvat'] = md5(microtime() . $filetmp);
    } else {
        $errors[] = 'There was a problem updating your avatar. Please try again.';
    }
}

However, this is not enough and does not allow my users profile page to work or look the way it should, I am going for something along the lines of how Google or Twitter do their avatar’s.

All help is appreciated. Cheers.

Advertisement

Answer

There is imagecrop() function in php:

$tmpfile = $_FILES['avatar']['tmp_name'];

switch ($fileext) {
 case 'jpg':
 case 'jpeg':
   $image = imagecreatefromjpeg($tmpfile);
   break;
 case 'png':
   $image = imagecreatefrompng($tmpfile);
   break;
 default:
   die("wtf is this extension??");
}

list($w, $h) = getimagesize($imgfile);
// get width $w and height $h for the image

if ($w < $h) // then keep the width and scale the height
 $image = imagecrop($image, array(
                              "x" => 0,
                              "y" => ($h - $w) / 2,
                              "width" => $w,
                              "height" => $w
                              ));
else if ($h < $w) // then keep the height and scale the width
 $image = imagecrop($image, array(
                              "x" => ($w - $h) / 2,
                              "y" => 0,
                              "width" => $h,
                              "height" => $h
                              ));

I haven’t tried this code but I’m quite sure it’s right. Try it and tell me if it doesn’t work.

UPDATE: Then you can save the resource $image with imagejpeg() or imagepng() to save the images with the same extensions so you won’t have problems with the database:

imagejpeg($image, "/path/to/your/image.jpg");
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement