NOTE: This script has been updated please see the following link PHP & jQuery image upload and crop v1.2 AND the new fully jquery’d version of it Jquery image upload and crop for PHP. Both new scripts handle JPG, GIF and PNG upload and crop!
We needed a PHP and jQuery image upload and crop tool and came up with the following. Hope it helps!
Before you start, ensure you have the following:
- PHP 4 or Higher (It has been tested on Version 5)
- PHP GD Library
- jQuery ver 1.2.3 or Higher
- Image Area Select plugin by Michal Wojciechowski
Our Requirement
What we needed was a way to upload a JPG image, resize it if required then crop it to given height and width.
1. Firstly we created a form to allow us to upload an image. Pretty basic, nothing flashy there.
2. Capture, rename and resize the uploaded file. (We also provided a set name for the uploaded file.)
if (isset($_POST["upload"])) {
//Get the file information
$userfile_name = $_FILES["image"]["name"];
$userfile_tmp = $_FILES["image"]["tmp_name"];
$userfile_size = $_FILES["image"]["size"];
$filename = basename($_FILES["image"]["name"]);
$file_ext = substr($filename, strrpos($filename, ".") + 1);
//Only process if the file is a JPG and below the allowed limit
if((!empty($_FILES["image"])) && ($_FILES["image"]["error"] == 0)) {
if (($file_ext!="jpg") && ($userfile_size > $max_file)) {
$error= "ONLY jpeg images under 1MB are accepted for upload";
}
}else{
$error= "Select a jpeg image for upload";
}
//Everything is ok, so we can upload the image.
if (strlen($error)==0){
if (isset($_FILES["image"]["name"])){
move_uploaded_file($userfile_tmp, $large_image_location);
chmod ($large_image_location, 0777);
$width = getWidth($large_image_location);
$height = getHeight($large_image_location);
//Scale the image if it is greater than the width set above
if ($width > $max_width){
$scale = $max_width/$width;
$uploaded = resizeImage($large_image_location,$width,$height,$scale);
}else{
$scale = 1;
$uploaded = resizeImage($large_image_location,$width,$height,$scale);
}
//Delete the thumbnail file so the user can create a new one
if (file_exists($thumb_image_location)) {
unlink($thumb_image_location);
}
}
//Refresh the page to show the new uploaded image
header("location:".$_SERVER["PHP_SELF"]);
exit();
}
}
3. Now that the image has been uploaded and saved to our folder we can use the “Image Area Select” plugin to crop our image.
It basically provides the coordinates to the server to handle the crop.
- x1, y1 = coordinates of the top left corner of the initial selection area
- x2, y2 = coordinates of the bottom right corner of the initial selection area
- width = crop selection width
- height = crop selection height
There are a number of options with this plugin which you can see using the link above. We opted for an aspect ratio of 1:1 (height and width of 100px) along with a preview of what we are actually going to crop.
Lets break it down, we first set the imgAreaSelect function to the image we want to crop, i.e. the one we just uploaded. As you can see, the aspect ration is set to 1:1, which means we are going to get a square selection. The “onSelectChange” is a callback function which runs the preview function when a change is made to the crop.
$(window).load(function () {
$("#thumbnail").imgAreaSelect({ aspectRatio: "1:1", onSelectChange: preview });
});
The preview function below, is run as soon as you create your selection. This places the right part of the image into the preview window. The second part of the function populates hidden fields which are later passed to the server.
function preview(img, selection) {
var scaleX = 100 / selection.width;
var scaleY = 100 / selection.height;
$("#thumbnail + div > img").css({
width: Math.round(scaleX * 200) + "px",
height: Math.round(scaleY * 300) + "px",
marginLeft: "-" + Math.round(scaleX * selection.x1) + "px",
marginTop: "-" + Math.round(scaleY * selection.y1) + "px"
});
$("#x1").val(selection.x1);
$("#y1").val(selection.y1);
$("#x2").val(selection.x2);
$("#y2").val(selection.y2);
$("#w").val(selection.width);
$("#h").val(selection.height);
}
This function is not really required, but helps by checking to see if the user has made a crop selection. In our case it is a required step. The form is submitted if the values exist, i.e. a selection has been made.
$(document).ready(function () {
$("#save_thumb").click(function() {
var x1 = $("#x1").val();
var y1 = $("#y1").val();
var x2 = $("#x2").val();
var y2 = $("#y2").val();
var w = $("#w").val();
var h = $("#h").val();
if(x1=="" || y1=="" || x2=="" || y2=="" || w=="" || h==""){
alert("You must make a selection first");
return false;
}else{
return true;
}
});
});
4. Finally it’s time to handle these new coordinates and generate our new cropped thumbnail.
if (isset($_POST["upload_thumbnail"])) {
//Get the new coordinates to crop the image.
$x1 = $_POST["x1"];
$y1 = $_POST["y1"];
$x2 = $_POST["x2"]; // not really required
$y2 = $_POST["y2"]; // not really required
$w = $_POST["w"];
$h = $_POST["h"];
//Scale the image to the 100px by 100px
$scale = 100/$w;
$cropped = resizeThumbnailImage($thumb_image_location, $large_image_location,$w,$h,$x1,$y1,$scale);
//Reload the page again to view the thumbnail
header("location:".$_SERVER["PHP_SELF"]);
exit();
}
That is pretty much it, and all it took was 2 javascript files! Take a look at the demo and download a copy to see the full working code.
So far we have tested it in FireFox v2, Internet Explorer 6 and 7 with pretty good results. (Let us know if you find any issues with other browsers.)
The demo
Click here to see it in action
Download
Found this article useful? Did it save you time?
Tags: crop, gd, image, Jquery, PHP, upload
Blogsphere: TechnoratiFeedsterBloglines
Bookmark: Del.icio.usSpurlFurlSimpyBlinkDigg
RSS feed for comments on this post | TrackBack URI for this post

Hi,
I need uploaded image and croped image display side by side at the width I have set .
At the moment when we upload a large image it is to large for the screen. and crop image go to beneth . 2 Images side by side would work better.
Please help me
regards
vishnu
Hi,
Sorry my English I’m from Brazil.
I downloaded of this source and to test it I´m using easyPHP, when I run the source dont show any lines with errors of php but show the follows message
“Unexpected Error
Please try again
Acesso Proibido! Você não tem premissão para acessar o objeto requisitado. Ele pode estar protegido contra leitura ou não ser legível pelo servidor. Se você acredita ter encontrado um problema no servidor, por favor entre em contato com o webmaster. Error 403 localhost 12/09/09 23:31:24 Apache/2.2.13 (Win32) PHP/5.3.0 ”
What i need to do to use it without this problem??
Thank
Sorry my English but I want to try…
@vishnu, if the large image is too big for the width then the thumbnail will not sit side by side. Either make the width of your site wider or make your larger image smaller to fit the screen.
@helio, ensure the upload directory has write permissions (CHMOD 777), you can comment out the error reporting line to see what errors may be causing this error:
change
error_reporting (E_ALL ^ E_NOTICE);
to
#error_reporting (E_ALL ^ E_NOTICE);
When I upload an image it saves the image like resize_34242.jpg.jpg
And i don’t want the images to be named resize_34242…
i want my images to be named like resize_(original file name).(file extension)
so much for the next version
Can’t get it to work, because of the file extension problem, probably because PHP version… don’t know what version is on, probably 4.x
this is a great script but i’m having a problem modifying it.
how can i make the upload directory change dyamically based on a $_GET variable posted from a url, i have tried modifying $upload_dir = “../images/”.$_GET['folder']; in image_functions but it posts it to the folder images/ instead ignoring the $_GET['folder']
Thanks
Hi! I wonder if you’re allowed to use this solution on -any- website?
nice script! thanks. Is there a way I can make multiple thumbnails? it would be great.
@Dac, please note all copyright notices must stay intact to use this solution
@keithics, Yes you can, you would need to call the resize function to obviously resize the thumbnails in the various sizes you want.
e.g. Call this function again but change the scale
$scale = ($thumb_width)/$w;
$cropped = resizeThumbnailImage($thumb_image_location, $large_image_location,$w,$h,$x1,$y1,$scale);
Saying this, you will have to give the new thumbnail a different name otherwise it will continue to get overwritten by the script. Remember to include the folder it has to be stored in too!
$scale = ($thumb_width*2)/$w;
$cropped = resizeThumbnailImage($upload_path.’my_new_thumbnail1′.$_SESSION['user_file_ext'], $large_image_location,$w,$h,$x1,$y1,$scale);
This should give you a new thumbnail that is twice the size of the width set at the very top. Although this has not been tested.
Excellent !!
Thanks for a very nice post. I implemented this and found it quite simple and nice. Currently I am making some image gallery with CakePhp and eager to implement this feature.
Please let me know if there is any implementation of this or any other feature in the same fashion with in CakePhp.
Regards,
Amjad Shaick
Thank you for your amazing script! It works like a charm. However, I came over with a problem when integrating it with a jQuery uploader rotine.
Problem is that, after I upload the image and dinamically display it inside a div, the “preview” function seems not to find the large image, doing nothing with the thumbnail preview. Here is a bit of the code:
onComplete: function(file, response){
button.text(‘Upload’);
window.clearInterval(interval);
// enable upload button
this.enable();
// add file to the list
$(”).appendTo(‘#example1 .files’).text(file);
$(‘#origImage’).prepend(”);
$(‘#thumbImage’).prepend(”);
$(‘#thumbnail’).imgAreaSelect({ aspectRatio: ‘1:1′, onSelectChange: preview });
}
Note that I just call the “preview” function, after having completed the upload and displayed the image.
Do you have any idea about what I am doing wrong on it? Any help would be very appreciated. Thank you!
hi,
thanks for the great script.
my problem is eventough folder permissions on server is correct and script works flawless on a local test machine. i cant upload images(or cant create them) to server.
any suggestions appreciated.
have nice day.
thanks man, this is really a great script
I want to have the original file name and extension. In this way now i can use only one image, that I always overwrite.
Anyone can tell me how to fix this? (will this be in the newer version?)
Just keep the file name
Works really nicely. Thanks for sharing.
Is it possible to let the user specify the dimensions of the cropped image? Say pass a width and height using an input alongside the upload form? That would be really cool.
Hi all,
This is great!
I was wondering if anyone knows how to create multiple versions of the cropped image for example: a large, medium and small version of the generated thumbnail?
Much appreciated,
Thanks! k
First, this is a pretty neat plugin. Thanks for it.
I’m having a problem with implementation. As a standalone version, it works just fine, but when I incorporate it it into my website, it breaks. I think it has to do with the jquery-pack. It occurs to me it already includes jQuery 1.2.6. My site is heavily reliant on jQuery, and I use a lot of different plugins. I already use goggleapi for my whole site (maybe thirty pages.) Do you have a version that doesn’t include the jQuery library, and just the jQ scripts needed for your plugin?
Again, thanks for the script, and in advance for any help you might give.
Oh man! This script is awesome!
Congratulations, it helped me a lot!!!
Hi,
This is perfectly useful.
But I am getting an error message
“Fatal error: Call to undefined function imagecreatetruecolor()”.
Please help me to sort it out
@jj, it seems you may not have the GD2 graphics manipulation library, you can check this out looking at the output of phpinfo(); If the file does exist, it must be enabled in php.ini by adding the following lines in the file:
[PHP_GD2]
extension=php_gd2.dll
It could be very useful to have a parameter to change the aspect ratio of the cropped image (currently i can only get square thumbnails) or to specify a fixed width & height for the cropped image. Can anyone help with this? How can i change the script to work in this way?
regards,
Hi,
I type all this for the second time – great product, just what we are looking for to allow end-users to easily upload and create thumbnail images.
There is one problem with the thumbnail preview, when an area is selected the preview window sometimes displays the top portion of the main image invading the bottom portion of the preview (at a rate roughly double the rate of mouse drag).
This seems only to happen when the image is quite deep, i.e. deeper than a 4:3 image
PS – its annoying to lose an entire technical comment just because I missed the CAPTCHA!