Reputation: 4378
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.
Upvotes: 0
Views: 2085
Reputation: 1817
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");
Upvotes: 4
Reputation: 22760
This is an explanation of how the process works, this is not a copy and paste code but a description of the logic processes you need to understand to resize images in PHP
You want to be using PHP imagecopyresampled
to take the original image and then work out mathematically the margins to make it a square and then resize that square.
Process:
Uploaded image is checked is a genuine image and genuine filetype.
Using imagecreatefromjpeg
(or similar ones for PNG etc.) you can import the uploaded image file resource.
Using getimagesize
you can find the dimensions, you can then find the aspect ratio of the image.
If the aspect ratio is > 1 then width is larger than height so you then need to assume a square the same size as height (as it's the smaller value). For example:
.
Width: 450
Height: 300
Ratio = 450/300 = 3/2 = 1.5 = >1
If the aspect ratio is <1 then the height is larger than the width.
So you want a square that is 300x300 so you need to cut off the excess 150 from the width. This is called the Margin, and to centre the image you need to cut off half of the margin from each side so:
.
$fullMargin = (width- height)
$margin = $fullMargin/2
.
$max_width = $max_height = 256;
$smallestDimensionValue = $originalHeight //(in this example);
$newImage = imagecreatetruecolor($max_width,$max_height);
$sourceHeight = $originalHeight;
$sourceWidth = $originalWidth - $fullMargin;
.
imagecopyresampled($nwImage, $sourceImage, 0,0,$margin,0,$max_width,$max_height,$sourceWidth,$sourceHeight);
imagecopyresampled
automatically, but to understand it, Once you've established the Margin size for the full size image you then have to multiply the margin by the same value as the width and the height to scale the overall image to the appropriate size. Say for example you want the avatar to have a maximum size of 256px then:
maximum_allowed_width / original_width = scale_factor.
So for the example above this is:
256 / 450 = 0.56888888
This is the value the margin value defined above, as well as the height and width of the destination image, is multiplied by.
Upvotes: 0