Class for picture upload with fix width and height
For one of my web 2.0 projects I had to develop a solution for users to upload their images with fixed width and height. Basically my customer wanted to display profile images on the start page, but the requirement was to display each of them in a div container with fixed width and height. Because I'm not a CSS guru and I didn't want to set negative background position to display only parts of the images or because of the problems, which CSS has with different browsers, I came up with a solution, which does that pretty good. My class has a simple configuration and according to the width or height of an image uploaded by a user, resizes it to predefined width or height and places it according to the case vertically or horizontally in the center. This description might be confusing right now, but if you read this post to the end I hope you will know, what I meant.
(You can find a downloadable archive at the end of this example)
Let's start with defining the class and some configuration variables.
[source:php]
class Upload {
private $image = array();
private $image_location;
private $image_type;
private $image_height;
private $image_width;
private $image_maxheight;
private $image_maxwidth;
private $image_box;
public $error;
public $success;
}
[/source]
We set all of important variables as private, because we will use them only in the scope of our class. Two public variables will be responsible for displaying the error and success messages. Let's go to our constructor.
[source:php]
function __construct() {
$this->image_location = 'images/';
$this->image_height = 60;
$this->image_width = 60;
$this->image_maxheight = 1500;
$this->image_maxwidth = 1500;
$this->image_box = 60;
}
[/source]
In our constructor method, which will be executed, after we initialize our class, we will define some basic configuration. $this->image_location property will tell our script, where to save the images. Before you start using this class, don't forget to create this directory and give it necessary rights, because otherwise you will get an error message. $this->image_width and $this->image_height tell our script, to which width or height should the image be resized. Both properties should have the same value, which shouldn't be bigger than the value of $this->image_box. Our script will automatically detect, if the picture is horizontal or vertical and will use the right value according to the case. $this->image_box tells our script, which resolution has the div box displayed on the start page. $this->image_maxheight and $this->image_maxwidth is the maximum resolution of the picture, which cannot be exceeded. Let's move to the picture upload.
[source:php]
public function uploadPicture() {
foreach($_FILES as $file) {
$this->image['tmp_name'] = $file['tmp_name'];
$this->image['name'] = $this->image_location.$file['name'];
$this->image['type'] = $file['type'];
}
return ($this->createPicture()) ? true : false;
}
[/source]
In our first public method, which will be called, after a user clicks an upload button, we set some important properties, which we will use later to handle our image upload. $this->image['tmp_name'] will hold for us the temporary location of the file. $this->image['name'] will hold the location, where the uploaded image should be copied, and $this->image['type'] will hold MIME type of the uploaded picture. After we set those properties, we call createPicture method to actually create the pictures for us. Let's take a closer look at two last methods.
[source:php]
private function createPicture() {
if($this->checkType()) {
move_uploaded_file($this->image['tmp_name'],$this->image['name']);
list($width, $height, $type, $attr) = getimagesize($this->image['name']);
if ($width > $this->image_maxwidth || $height > $this->image_maxheight) {
$this->error = 'Your picture is too big';
unlink($this->image['name']);
return false;
} else {
if($height > $width) {
$this->image_width = round((($this->image_height * $width) / $height));
$x = round(($this->image_height - $this->image_width) / 2);
$y = 0;
} else {
$this->image_height = round((($this->image_width * $height) / $width));
$x = 0;
$y = round(($this->image_width - $this->image_height) / 2);
}
if($this->image_type == 'jpg') {
$galery_image = imagecreatefromjpeg($this->image['name']);
} elseif($this->image_type == 'gif') {
$galery_image = imagecreatefromgif($this->image['name']);
} else {
$galery_image = imagecreatefrompng($this->image['name']);
}
$image = imagecreatetruecolor($this->image_box, $this->image_box);
$background = imagecolorallocate($image, 255, 0, 0);
imagefill($image, 0, 0, $background);
imagecopyresampled($image, $galery_image, $x, $y, 0, 0, $this->image_width, $this->image_height, $width, $height);
if($this->image_type == 'jpg') {
imagejpeg($image, $this->image['name']);
} elseif($this->image_type == 'gif') {
imagegif($image, $this->image['name']);
} else {
imagepng($image, $this->image['name']);
}
chmod($this->image['name'], 0644);
imagedestroy($image);
$this->success = 'Image uploaded successfully';
return true;
}
} else {
return false;
}
}
private function checkType() {
switch ($this->image['type']) {
case 'image/jpeg':
case 'image/jpg':
case 'image/pjpeg':
$this->image_type = "jpg";
return true;
break;
case 'image/gif':
$this->image_type = "gif";
return true;
break;
case 'image/png':
case 'image/x-png':
$this->image_type = "png";
return true;
break;
default:
$this->error = "Wrong file type";
return false;
break;
}
}
[/source]
Because this two method are pretty long I will split them into smaller pieces and explain step by step. We set both of the methods as private, because we will use them only in the scope of our class. It the first method, createPicture, we first check, if the MIME type of the file uploaded by a user is supported by our script. If it is we set $this->image_type and return true, if not we display error message and return false.
[source:php]
move_uploaded_file($this->image['tmp_name'],$this->image['name']);
list($width, $height, $type, $attr) = getimagesize($this->image['name']);
if ($width > $this->image_maxwidth || $height > $this->image_maxheight) {
$this->error = 'Your picture is too big';
unlink($this->image['name']);
return false;
}
[/source]
In this part we actually move the uploaded file from the temporary location to the location we defined earlier in our script. After that we list the width and height from our new uploaded image and check, if they are not bigger, then the values we defined in our constructor. If they are, we display an error message, if not we proceed.
[source:php]
if($height > $width) {
$this->image_width = round((($this->image_height * $width) / $height));
$x = round(($this->image_height - $this->image_width) / 2);
$y = 0;
} else {
$this->image_height = round((($this->image_width * $height) / $width));
$x = 0;
$y = round(($this->image_width - $this->image_height) / 2);
}
[/source]
If the resolution of the image is correct, we check, if the image is vertical or horizontal. According to the case, we calculate new width or new height and the offset, which we will later use to place the image in the middle of our box.
[source:php]
if($this->image_type == 'jpg') {
$galery_image = imagecreatefromjpeg($this->image['name']);
} elseif($this->image_type == 'gif') {
$galery_image = imagecreatefromgif($this->image['name']);
} else {
$galery_image = imagecreatefrompng($this->image['name']);
}
$image = imagecreatetruecolor($this->image_box, $this->image_box);
$background = imagecolorallocate($image, 255, 0, 0);
imagefill($image, 0, 0, $background);
imagecopyresampled($image, $galery_image, $x, $y, 0, 0, $this->image_width, $this->image_height, $width, $height);
[/source]
In this step we return an image identifier according to the MIME type of the picture, which has been uploaded and create an empty image, in which we will place the uploaded picture. You can change the $background and use your own color for the background using the RGB values. Imagecopyresampled uses our identifier and the "picture box" we creted with predefined values and creates a ready image.
[source:php]
if($this->image_type == 'jpg') {
imagejpeg($image, $this->image['name']);
} elseif($this->image_type == 'gif') {
imagegif($image, $this->image['name']);
} else {
imagepng($image, $this->image['name']);
}
chmod($this->image['name'], 0644);
imagedestroy($image);
$this->success = 'Image uploaded successfully';
return true;
[/source]
In the last part, according to MIME type, we output our new created picture to the file, change the permissions and destroy the original image.
Let's take a closer look, how you should use this class.
[source:php]
if(isset($_POST['submit']) && $_POST['submit'] == 'upload') {
include('upload.class.php');
$upload = new Upload;
if($upload->uploadPicture()) {
echo (isset($upload->success)) ? $upload->success : '';
echo '
go back';
} else {
echo (isset($upload->error)) ? $upload->error : '';
echo '
go back';
}
} else {
?>
}
?>
[/source]
I think, this code doesn't need a detailed explanation. One hint only: don't forget to set the enctype of the form to multipart/form-data, because otherwise the $_FILES variable wont be initialized. If user clicks on upload button, we initialize our class and use the uploadPicture method to create our new picture. If this method returns true we display success message, if not the error message.
That's all. I hope it was clear enough for you, what I was trying to accomplish in this example. You can change it in probably hundreds different ways and adjust it to your own needs. Feel free to do that.
You can download all of the files here.