NOTE: Please update your browser. We recommend using IE 7 or FireFox 3.

PHP & jQuery image upload and crop v1.2

September 6th, 2008 | Posted in Ajax, Articles, Jquery, PHP | 40 Comments »
Tags: , , , , ,

PHP & jQuery image upload and crop v1.1

Update

Due to popular demand, further updates have been made to this script, to allow upload of JPG, GIFs and PNG images! Same great functionality now even more useful.

Please note the old script is still available at PHP & jQuery image upload and crop.

If you are not familiar with the concept, it may be worth reading the old article first.

Fixes

  1. You can now upload different types of images, JPG, GIFs and PNG
  2. You can now upload images and have a random file name (this fixes the caching issue some of you have had)
  3. The image upload error check has been fixed (thanks to DevWooty)

As with the previous script, ensure you have the following:

Basic overview

1. We will be using the session variable to hold the random file name (in our case the timestamp).
We are now also storing the file extension that is passed through the script, to ensure we are dealing with the right type of image.

	//only assign a new timestamp if the session variable is empty
	if (strlen($_SESSION['random_key'])==0){
	    $_SESSION['random_key'] = strtotime(date('Y-m-d H:i:s')); //assign the timestamp to the session variable
		$_SESSION['user_file_ext']= "";
	}

NOTE: Once the thumbnail is created we set the session variable to equal nothing, this will then allow a new image to be uploaded along with a new name.

2. Capture, rename and resize the uploaded file.
The validation section has also been updated and been made more secure by checking the mime type as well as the image extension.

		foreach ($allowed_image_types as $mime_type => $ext) {
			//loop through the specified image types and if they match the extension then break out
			//everything is ok so go and check file size
			if($file_ext==$ext && $userfile_type==$mime_type){
				$error = "";
				break;
			}else{
				$error = "Only ".$image_ext." images accepted for upload";
			}
		}
		//check if the file size is above the allowed limit
		if ($userfile_size > ($max_file*1048576)) {
			$error.= "Images must be under ".$max_file."MB in size";
		}

3. Same as before, we grab the coordinates using the imgAreaSelect plugin and send the details to the server.

  • 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.

NOTE: Using the php calculation below makes the script that much more dynamic, all you now have to do is set the height and width of your thumbnail and the script will calculate the ratio/preview sizes for you! (Thanks to Long for the tip.)

$(window).load(function () {
	$("#thumbnail").imgAreaSelect({ aspectRatio: "1:thumb_height/thumb_width", 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 =  / selection.width;
	var scaleY =  / selection.height; 

	$('#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'
	});
	$('#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 = $thumb_width/$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();
}

Take a look at the demo and download a copy to see the full working code.

So far we have tested it in FireFox 2 and 3, Internet Explorer 6 and 7 and Safari 3.1.2 with pretty good results. The only issue we found was when uploading transparent gifs and pngs results in a black background.

The demo

Click here to see it in action

Download

Click here to download v1.2 [JPG, GIF, PNG]
Click here to download v1.1 [JPG ONLY]


Found this article useful? Did it save you time?



Tags: , , , , ,

Blogsphere: TechnoratiFeedsterBloglines
Bookmark: Del.icio.usSpurlFurlSimpyBlinkDigg
RSS feed for comments on this post

40 Comments to “PHP & jQuery image upload and crop v1.2”

  • dydream says:

    Just wanna let you know that I’ve been working on a WordPress function and your previous script was a BIG help for me. I’ll be checking out this new one and see what I can improve on.

    I thank you very much!

  • Dustin says:

    your script is so close to perfect for me. Can you help me take it one step further? Once the pic is uploaded and the user has selected the area they want to thumbnail, can you help me insert the ability to watermark it? (watermark will stay at 100 by 100 dimensions) Also, could I send the new filename into a mysql database? Please let me know how I can insert this into the script. Thanks

  • Dustin says:

    never mind, I got it. it was working but my png file was not saved in ‘indexed’ so it wasn’t working before.

  • Dydream says:

    Has anyone used this script in Konqueror (under Linux) ?

    Michal’s Image Area Select plugin turns the large image black, and the crop are white during cropping.

  • Michal Wojciechowski says:

    @Dydream:
    Please try the latest version (0.5.1), it should fix the problem.

  • webmotionuk says:

    @Michal we will include your updated version in the download

  • [...] By the way, remember the PHP image cropping tutorial I mentioned in my last post? WebMotionUK just published an updated version of it. [...]

  • daemon says:

    this is perfekt work..!!!

  • nickstaw says:

    Great work all round chaps. Looks like it will be extremely useful.

    Just one thing that I ask in ignorance. I am trying to get the name of the file to be the same as the original filename. I have located the variable ($userfile_name = $_FILES['image']['name'];) but I can’t for the life of me work out where I need to insert it to make it work. Please could someone help out as I’m tearing out what little of my hair I have left!!

    Many thanks in advance

  • webmotionuk says:

    @daemon & @nickstaw, thanks for the comments.
    @nickstaw, you basically have to use the $large_image_location and set that to the original file name, however, you will need to pass this name throughout the script therefore saving the name of the original file in a session will do the trick.

  • Claudiu says:

    Unfortunately it does not work all that well on google chrome, it uploads the image but does not go tot the crop image part.

  • munky says:

    hi, i tried to use it but after i load the image this is what i get “Fatal error: Call to undefined function: image_type_to_mime_type() in c:\apache\htdocs\upload_crop_v1.2.php on line 5″

    what am i doing wrong?

  • webmotionuk says:

    @munky, the image_type_to_mime_type() function is a built in PHP function more details can be found here http://uk2.php.net/image_type_to_mime_type, this function has been found to create problems in PHP versions older than 4.3.

    in our code, just above the image_type_to_mime_type function there is the following:

    list($imagewidth, $imageheight, $imageType) = getimagesize($image);
    $imageType = image_type_to_mime_type($imageType);

    change it to

    list($imagewidth, $imageheight, $imageType, $bits, $channels, $mime) = getimagesize($image);
    $imageType = $mime;

    You will need to change it in both the image resize functions
    starting line: 56 – resizeImage() function and
    starting line: 97 – resizeThumbnailImage() function

    Hopefully that should do the trick.

  • Honish says:

    It is wonderful. But we have one issue in IE 7. If we left double click on image instead of cropping area select then getting a JavaScript error “Invalid arguments”. But working fine with Firefox. Any idea to fix this issue.

    Thanks in advance
    Honish

  • nicos says:

    In script 1.0, it was possible to re-upload a file if the uploaded picture didn’t (on the screen you resize the pic.)

    In 1.2 version, it seems this feature isn’t avaible anymore. How can i solve this problem? Thanks

  • webmotionuk says:

    @nicos, could you please specify again what it is you need, your comment doesn’t really make sense. in both scripts you are able to re-upload a new image once a crop has been made.

  • nicos says:

    it’s a mistake from me,sorry.
    thank you for your fast reply

  • huzzi says:

    Is it possible to make the thumbnail overlay visible on load?

    thanks

  • webmotionuk says:

    @huzzi,

    Find and change the following line
    $(’#thumbnail’).imgAreaSelect({ aspectRatio: ‘1:1′, onSelectChange: preview });
    to
    $(’#thumbnail’).imgAreaSelect({ x1: 120, y1: 90, x2: 280, y2: 210, aspectRatio: ‘1:1′, onSelectChange: preview });

    Obvioulsy the x1,y1,x2,y2 values above are just an example and may not work on your image. Adjust as necessary.

  • huzzi says:

    Brilliant, thanks so much.

  • Arnold Goetzke says:

    Nice script…

    Can someone crop an image that is larger than the screen size?

    Is it possible for someone to download what they just cropped?

    Thanks,,,

    AG

  • adrian says:

    Very nice script…

    I’m trying to do the same thing as huzzi – got the thumbnail overview loading up perfectly on load, but is there a way to ensure the thumbnail matches this on load (as opposed to on mouse interaction)?

    Thanks,
    Adrian

  • Brandon says:

    Thanks for the script … very useful!

    I’m having an issue with the selection tool in IE7. I’m working off of your upload_crop_v1.2.php file “as is”. I was able to upload a photo, but when I go to make the selection, I get an error:

    Line: 13
    Char: 12949
    Error: Invalid argument
    Code: 0
    URL: …/upload_crop_v1.2.php

    Things are working fine in Firefox though. I also looked at your demo in IE7 and it works fine. Any ideas?? I could be overlooking something simple.

    I’m using jquery-1.3.2.min.js and jquery.imgareaselect-0.8.js.

  • Kyaan says:

    Hi, I am trying to use this great plugin in a JQuery Dialog but I’m having issues with z-index of the selection div,

    I tried (with no result):
    $(’.imgareaselect-outer’).css(z-index:2000 !important;);
    $(’.imgareaselect-selection’).css(z-index:2000 !important;);

    Do you know a way to fix this please?

  • webmotionuk says:

    @Kyaan, your css command for jquery is incorrect, please see the jquery documentation on applying css to elements,

    $(”.my_element”).css(”color”,”#ffffff”)
    Try
    $(”.my_element”).css(”z-index”,”200″)

  • Kyaan says:

    Thank you very much, it’s working perfectly on both IE & FF now!

  • dydream says:

    webmotionuk,

    Does this PHP script work in safe_mode = ON?

  • webmotionuk says:

    @dydream, safe_mode must be off for this script to work.

  • JPM says:

    Brilliant

  • alex says:

    Hi webmotionuk,

    I have an issue with IE 6, when i upload an image for the first time, the cropping tool isn’t visible. After i close the window with your script and reopen >> reupload >> i can see the cropping tool.

    This only appears in IE6 at the moment

    Any advice??

  • SCK says:

    Do you know of a method to add text to uploaded images?

  • shin says:

    Thanks.

    I wonder how I can crop image with different sizes.

    Can anyone enlighten me how to do it?

  • webmotionuk says:

    @shin, you can crop at different sizes, however it will require you to edit the script to remove the elements that define the thumbnail size and replace it with your own. Also a preview may not be possible for images that do not have a fixed thumbnail height and width.

  • Higor says:

    WOW!!!!!!!!!!!!!!
    The best upload script ever, 100% customizable.
    Here’s one contribution:
    At the line where is the Image to Crop add “cursor:crosshair” at the style.
    The changed version is:
    <img src=”" style=”float: left; margin-right: 10px;cursor:crosshair” id=”thumbnail” alt=”Create Thumbnail” />

    And it will show a cross when mouse is hover.

    Thanks a lot
    Higor
    higorvaz@gmail.com

  • Dan says:

    I believe I may have found a bug.

    I set max_file to “5″ and max_width to “640″

    I then tried to upload a 4.5 MB JPG which then returns a blank page without the crop features. I hit the back button which then reveal the original image of 2304×3072 with the crop features but these don’t work.

    I was just testing how a user might realistically upload a photo after directly docking their camera. I advise that you use this same test scenario to counter the bug.

  • Fredrik says:

    Hi,

    I think this is a very cool application but would like to tweak it a little bit. I would like not to have to upload the image before making the crop selection. I can get the image in the cropping area fine and the selection works perfectly but here’s the question:

    How wolud I go about changing the php-script so that it uploads a file I specified in the form posted (not in a file-type input field but a hidden one)? And then does the same cropping as the original script, of course.

    Thanks in advance!

    Fredrik

  • Peter says:

    Hi,

    Great script, thank you very much – actually it’s one of the best image upload scripts I’ve seen. However, I’m having little compatibility issues on IE8 and FF3.5.

    on IE8 – works only in compatibility mode.
    on FF3.5 – doesn’t get to the crop part at all.

    I was wondering if anyone else is having similar issues?

    Peter

  • Peter says:

    Figured it out – it was obviously my mistake..
    Thanks again for the great piece of code.
    Peter

  • Rolf says:

    Hello everyone,

    Thank you for promoting this script, I really like… But I have one big issue, which I’m not able to figure it out, maybe someone of you guys can help me out.

    In the first step of the script I’m trying to implement a “uploadbar” which shows the process of uploading the “big”-first image… Maybe someone can share an example with me or help me with some tips?

    Thanks for that!
    Rolf

  • Pradish says:

    Hi,

    I am trying to implement your code , I have a list of profiles for which i need to upload images. I have successfully implemented the upload feature and thumbnail generation. Now the problem is when i delete the image for one profile and then come back and add an image for the same profile, it always displays the previous image (cache). This works fine in FF ,but IE is loading images from cache…any idea how to solve this. I have added no cache header to the page but still it is cachin the image..

    Thanks
    Pradish

Post comment