We are looking for new features to be added to this plugin, please leave your requests in the comments on the following page : JQuery / PHP Upload and Crop – Feature Request
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:
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.
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.)
Click here to see it in action
@Oya, the reason we haven’t used the original image is because we wanted it to fit within our site’s width. So if a user uploads an image which is 1000pixels wide and our site only has say 600px of space, its not really going to work…The whole look and feel of the site will be broken because of that large image being displayed.
There is no reason why you cannot edit the script to have it the way you want i.e. using the original image, the script is pretty well commented, and shouldn’t be difficult to achieve. There are also options to restrict the width of the original image (you can set this to as big as you want), so its fairly configurable. Although saying that, uploading very large images causes memory issues, so beware. (http://www.webmotionuk.co.uk/jquery-image-upload-and-crop-for-php/#comment-677)
This is a pretty nice script. But what I don’t understand is why you don’t use the original uploaded image when you make the thumbnail. If the previewimage and the thumbnail are the same width, you get bad quality if you decrease the width of the crop.
@ lapubell tankyou
@ webmotionuk this tutorial fills a huge void in 80% off the webapps i’m aware. You Guys rock
Great tool!
@RUI, the original file name is stored in the variable $userfile_name. you can do anything you want to with that name.
Just wanted to say thanks and I might bundle this up for a few upcoming projects. I’ll include a link to my version of this when I’ve kicked out all the bugs.
Superb*****
Now a newbie question
I need to keep the original file name instead of $_SESSION['random_key'] how can i do this?
Tanks in advance
First off.. great script! One quick question. What would be needed to have the script make two new cropped images instead of just one. I’d like to try and get it to make a small version and large version of the cropped image. Thanks for making this available on your site! Great documentation as well.
Hi, I’m testing this on an internal site and found that some users “ASSUME” that when they click “create thumbnail” that the program automatically does it. So I’m wondering if there’s a way to give people the option of either cropping a pic, or just having the program create a thumbnail automatically if they’re lazy of the original pic – how would this look in your program?
Thanks for this wonderful tool.
Paul
Great Script, however I cannot for the life of me figure out the preview instance function.
function preview(img, selection) {
… $(‘#thumbnail + div > img’).css({
width: Math.round(scaleX * ) + ‘px’,
height: Math.round(scaleY * ) + ‘px’,
marginLeft: ‘-’ + Math.round(scaleX * selection.x1) + ‘px’,
marginTop: ‘-’ + Math.round(scaleY * selection.y1) + ‘px’
});
…
I want to place the preview image in a TD ( clients wishes, ugh). If the preview DIV gets placed into a TD, the onselect doesnt activate. I dont know much JS. Any ways I can make the function work for a TD?
@craig, if you are not updating the images on a regular basis then delete the row and re-insert with the new data. Or depending on the database structure, if you are using a linking table then you can just delete the blob and re-insert into the linking table, and use an update statement for the main text content. if you require further help, please email us your code using our contact form, we will see what we can do.
A superb script – thankyou. I had been trying to find a way to allow a user to crop an uploaded image prior to inserting it as a blob into a mysql database (I know it’s not a ‘good’ thing to do but it will only ever have 10 or so images stored at any one time) I have now done it using your code.
The only outstanding issue I have is trying to edit an existing posted article. All I need to do is allow the user to change the photo stored as a blob for another one – not actually edit the blob. Have a play at http://www.motors4less.net/uploader.php if you wish. Image size limited . Just try editing an existing article and uploading a new image to crop.
In case preview not at top and left,I dont know how to set default x1,y1 of preview, anyone tell me how to set it? Thanks a lot!
Nice script …
@Mark, to use a default image you will need to set the variable on line 61 to the name of your image as shown below:
$large_image_name = “my_picture.jpg”;
Ensure the image exists in the folder which is on line 59.
$upload_dir = “upload_pic”;
Your picture will then appear as default when you visit the page.
NOTE: you will need to remove lines 153 to 155 (if (file_exists($large_image_location)) {…}) so that the default image is not deleted along with the thumbnail.
Nice script, very cool.
Like in the example, how can a default image be defined?
Thanks
@Mayya, thank you for your comments, you can adjust the proportion of the crop by selecting the size of the thumbnail your require. The proportions are automatically calculated. (1 : thumb_height/thumb_width)
Please ensure you are using the latest version as this one only supports JPG images.
Very nice application! Great Work!
I’d really appreciate if you could add an option for image proportion because most of the time we don’t want an image with the same width and height.
Keep it up.
Very nice script!
I just wonder if it is possible to make it “aspect free” ?
BTW, great script!!!
Hi, is there any possible way to make the size of selection a default size and in a way where users can move the selection around the actual image but not resize it?
Really nice script, this is exactly what I was looking for. However, I was looking for at least three types of images(JPG, GIF, PNG). It dosen’t work for GIF and PNG. Could you please let me know if you have other version with this support? right now images are coming as black.
This is a beautifully written script. I placed it on my website as a profile picture uploader. I was also wondering the same thing as Fredrik: how do I get this to work with a random image name?
Really great script!
Could you post the solution for a random filename that you mailed Frederik? I’ve been trying but I can’t get it to work. For example: How can I add a timestamp to the filename?
EXACTLY what I was looking for, wonderful, perfect!
Hello, how can I add a random(); to generate the name of the uploaded file…?
Please emalil me someone at erisone(a)gmail.com, thanks!
a question, as I do so that the thumbnail is a rectangle rather than a square thanks
This is great, worked first time, and Long’s snippet is great too.
Regarding the caching of images, just throw a random querystring on the image [ I just use ?t= ], and it won’t cache.
great script! but it just dont work well on explorer 7. you need to hit refresh to see new image
is there any solution for this issue? thank you
This is an amazing script =) I love it… i had to change some few thing in it but i didnt get it to work with a random_key for the pic file name, so i just emailed the creator of the script…
and then after 12hours the answer where in my inbox… and now it works perfecly finr!
Thanks for a GREAT script, i be back for more =P
//Fredrik, Sweden
Thanks for your work, thats a really nice image facility. I am going to use this for our website for sure. keep up the great tutes and work!
The http://www.webmotionuk.co.uk is cool site, good job
I appreciate this… it is exactly what I was looking for!
Your blog is interesting!
Keep up the good work!
Great stuff \o/
Does anyone know how to make it works with Thinkbox jQuery ?
That would be a way to use the crop when you do not have enough space on your page.
Great work.. thanks.
great job! Looking forvard for resize and rotate image functionality)
Opps – too quick with the click button.
I also wanted to say – great job. This is an excellent piece of work.
Cheers
I think you meant
(($file_ext != "jpg") || ($userfile_size > $max_file))rather than
(($file_ext != "jpg") && ($userfile_size > $max_file))Cheers
Can you mod it to let users pick the cropping size from a drop down menu?
thanks
It is not trivial where you’ve got scaleX * 200 and scaleX * 300 when the Ferrari demo pic is 500 x 375. I figured that the proportions are the same, but couln’t you simplify it?
Looks cool. Thanks
I was thinking about having an image up load feature. Learning how to implement the upload feature was the fun part.
Nice compilation, thanks, especially for JS part.
As for PHP part, i wonder why not use php native imagesx() and imagesy() instead of writing new getWidth() and getHeight().
Thanks, that did the trick. The problem was having “$(window).load(function () {“
@chris,
This is the original code:
$(document).ready(function(){
$('#asdf').slideDown('slow');
});
$(window).load(function () {
$('#asdf img').imgAreaSelect({ maxWidth: 20, maxHeight: 20 });
});
Try this instead:
$(document).ready(function(){
$('#asdf').slideDown('slow');
$('#asdf img').imgAreaSelect({ maxWidth: 20, maxHeight: 20 });
});
The imageareaselect will be called after the image is loaded, You could even put this into a click function as follows:
$(document).ready(function(){
$('#button').click(function() {
$('#asdf').slideDown('slow');
$('#asdf img').imgAreaSelect({ maxWidth: 20, maxHeight: 20 });
});
});
Let us know how you get on.
Here is the description of the problem
http://www.nabble.com/imageAreaSelect-bug-td17861390s27240.html
Im also experiencing problems if the img element does not have a width and height initially set. Why you might ask? Becasue I am loading content dynamically via AJAX calls
@chris, why are you hiding the image in the first place? you may need to use livequery to pick up new elements introduced via JS. There is further information on the “image area select” plugin on the creators home page, see the link at the top of this page.
Or give us a more detailed explanation of what you are trying to achieve, and if its relevant we can include it in the download.
This plugin does not work if the img element was previously hidden and then displayed again via js. Seems to be a bug thats needs to be addressed
@long, thats correct, your addition makes it that much more dynamic.
text was cut off. correct change:
$(‘#thumbnail’).imgAreaSelect({ aspectRatio: ’1:<?php echo $thumb_height/$thumb_width;?>’, onSelectChange: preview });
Thanks for the interesting script!
However, it should be amended to read:
line # 240 ($(‘# thumbnail ‘). imgAreaSelect)
should be changed to:
$(‘#thumbnail’).imgAreaSelect({ aspectRatio: ’1:’, onSelectChange: preview });