Skip to content

How to crop an image using jQuery and PHP

So, your client uploaded the image into your newly, freshly developed CMS and then called you to yell about distorted image, or image that just does not look good?

That is a well known scenario. Let me explain a bit what we will achieve today. When your client uploads an image, he is taken to an Image edit area where he sees uploaded image and a smaller preview window. He just needs to drag on the larger image to select crop area and press submit.

After that you crop the image using PHP GD functionality and save the new image somewhere on disk.

Cropping refers to the removal of the outer parts of an image to improve framing, accentuate subject matter or change aspect ratio.

I will concentrate mainly on Image editor part, assuming that the client has uploaded the image. So here is our markup:

[code lang=”html”]
<p>Drag on the larger image to select crop area.</p>
<p>
<img id="photo" src="photo.jpg" alt="" title="" style="margin: 0 0 0 10px;" />
</p>
[/code]

So, we have an image tag with id and some inline styling. We will help ourselves with jQuery plugin which will achieve actual client side functionality without coding it from scratch. So, please go to ImgAreaSelect jQuery plugin page and download the plugin.

Extract css and scripts folder in your working folder and put this in your HTML’s head section:

[code lang=”html”]
<link rel="stylesheet" type="text/css" href="css/imgareaselect-default.css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="scripts/jquery.imgareaselect.pack.js"></script>
[/code]

Now, you are ready to rock and roll. As I said earlier, we will show a preview to the user, so let us create it using jQuery:

[code lang=”javascript”]
$(document).ready(function () {
$(‘<div><img src="photo.jpg" style="position: relative;" /><div>’) .css({
float: ‘left’,
position: ‘relative’,
overflow: ‘hidden’,
width: ‘100px’,
height: ‘100px’
}) .insertAfter($(‘#photo’));
});
[/code]

What this code does is add a div with size 100x100px and puts our image in it. Let us create some cropping functionality, so change the above code like this:

[code lang=”javascript”]
$(document).ready(function () {
$(‘<div><img src="photo.jpg" style="position: relative;" /><div>’) .css({
float: ‘left’,
position: ‘relative’,
overflow: ‘hidden’,
width: ‘100px’,
height: ‘100px’
}) .insertAfter($(‘#photo’));

$(‘#photo’).imgAreaSelect({
aspectRatio: ‘1:1’,
handles: true,
onSelectChange: preview
});
});
[/code]

We added a call to our plugin, set some parameters and a callback function which will preview our image in a smaller div. This function looks like this:

[code lang=”javascript”]
function preview(img, selection) {
var scaleX = 100 / (selection.width || 1);
var scaleY = 100 / (selection.height || 1);
$(‘#photo + div > img’).css({
width: Math.round(scaleX * 600) + ‘px’,
height: Math.round(scaleY * 400) + ‘px’,
marginLeft: ‘-‘ + Math.round(scaleX * selection.x1) + ‘px’,
marginTop: ‘-‘ + Math.round(scaleY * selection.y1) + ‘px’
});
}
[/code]

Let me explain a bit. Our plugin will send two parameters to out callback function, and image and selection. Selection is an object which contains width, height and borders of our selection.

Then we set scaling variables and by changing CSS properties of our preview div, we are showing the preview image to our user. Go ahead and try this. Awesome, isn’t it?

But, what now? This is useless. As much as it looks great, it does nothing. To provide cropping parameters to PHP file, we must use a form in which the parameters will be stored and then passed to PHP.

So let us add a form below our image, so our markup looks like this:

[code lang=”html”]
<p>
<img id="photo" src="photo.jpg" alt="" title="" style="margin: 0 0 0 10px;" />
</p>

<form action="crop.php" method="post">
<input type="hidden" name="x1" value="" />
<input type="hidden" name="y1" value="" />
<input type="hidden" name="x2" value="" />
<input type="hidden" name="y2" value="" />
<input type="hidden" name="w" value="" />
<input type="hidden" name="h" value="" />
<input type="submit" value="Crop" />
</form>
[/code]

Now let us adjust our JavaScript so it writes values to our form fields. Complete code looks like this:

[code lang=”javascript”]
function preview(img, selection) {
var scaleX = 100 / (selection.width || 1);
var scaleY = 100 / (selection.height || 1);
$(‘#photo + div > img’).css({
width: Math.round(scaleX * 600) + ‘px’,
height: Math.round(scaleY * 400) + ‘px’,
marginLeft: ‘-‘ + Math.round(scaleX * selection.x1) + ‘px’,
marginTop: ‘-‘ + Math.round(scaleY * selection.y1) + ‘px’
});
}

$(document).ready(function () {
$(‘<div><img src="photo.jpg" style="position: relative;" /><div>’) .css({
float: ‘left’,
position: ‘relative’,
overflow: ‘hidden’,
width: ‘100px’,
height: ‘100px’
}) .insertAfter($(‘#photo’));

$(‘#photo’).imgAreaSelect({
aspectRatio: ‘1:1’,
handles: true,
onSelectChange: preview,
onSelectEnd: function ( image, selection ) {
$(‘input[name=x1]’).val(selection.x1);
$(‘input[name=y1]’).val(selection.y1);
$(‘input[name=x2]’).val(selection.x2);
$(‘input[name=y2]’).val(selection.y2);
$(‘input[name=w]’).val(selection.width);
$(‘input[name=h]’).val(selection.height);
}
});
});
[/code]

Now whenever you complete selection (release a mouse button), callback function writes 4 coordinate values into our form fields. After we click Crop button, this parameters are sent to PHP file crop.php, which will crop the image and save it to disk. This is the code in crop.php:

[code lang=”php”]
// Original image
$filename = ‘photo.jpg’;
//die(print_r($_POST));
$new_filename = ‘photo1.jpg’;

// Get dimensions of the original image
list($current_width, $current_height) = getimagesize($filename);

// The x and y coordinates on the original image where we
// will begin cropping the image, taken from the form
$x1 = $_POST[‘x1’];
$y1 = $_POST[‘y1’];
$x2 = $_POST[‘x2’];
$y2 = $_POST[‘y2’];
$w = $_POST[‘w’];
$h = $_POST[‘h’];

//die(print_r($_POST));

// This will be the final size of the image
$crop_width = 100;
$crop_height = 100;

// Create our small image
$new = imagecreatetruecolor($crop_width, $crop_height);
// Create original image
$current_image = imagecreatefromjpeg($filename);
// resamling (actual cropping)
imagecopyresampled($new, $current_image, 0, 0, $x1, $y1, $crop_width, $crop_height, $w, $h);
// creating our new image
imagejpeg($new, $new_filename, 95);
[/code]

And that’s it. You can see the demo below. Demo only shows client side functionality for security reasons.


If you have any questions, please ask below in comments. I would love to help you.

Tags:

9 thoughts on “How to crop an image using jQuery and PHP”

  1. Pingback: Interesting things – October 15, 2010 « Daniel Botelho

  2. Sorry, but imagecopy don’t work correctly!.
    We need use imagecopyresampled, and $_POST x2, y2

    I liked this. I will post in my blog, in portuguese, ok?

    1. Hi Falci,

      I corrected the error. My mistake while copy/pasteing.

      You can post this, but please link back to this post.

      Thanks

  3. Pingback: links for 2010-11-23 | Midashuang's Blog

  4. Interesting article, I’ve used it as a reference to integrate the imgAreaSelect, cakephp and a cakephp component to redimension images.
    There’s a little thing I don’t understand, are x2 and y2 needed for something or just using w and h are enough to resample?
    I haven’t finished my scripts…
    sorry for my english, greetings from Argentina 🙂

  5. Thanks for the explanation,

    In your code, the original width and height of the image is fixed (600×400)

    How can you do when the image is loaded in runtime and you don’t know is size but don’t wan’t to display a 1440px wide image ?

    1. Reply to myself,

      Just use img.width and img.height and set fixed width for #photo !

      Thanks again

      regards

Comments are closed.