JCrop Extension Implementation In PHP

18th March 2009

I came across a really nice looking plugin for JQuery the other day that allowed you to select part of an image. This plugin is called JCrop.

This plugin supports things like thumbnail generation, animation, styling and event handling. The only problem is that this is all done on the client side, there is one example of a PHP script that resizes images using PHP, but this only works with JPEG images. The site says that improvements to the code are left as an exercise to the reader, so I though I would take a shot at it.

Rather than start from scratch with the PHP implementation I have adapted the ImageResize class that I talked about some months ago. I have changed the name to ImageManipulation as it has gone beyond a simple image resizing class.

I won't post the entire source code of that class here as it will take up too much space, instead I will provide a link to it.

#! code ImageManipulation class.

I'm going to be using the same JavaScript code from the Jcrop website example, but for convenience I will reproduce it here with some small changes. Basically I have removed all unnecessary HTML, included a DOCTYPE declaration, cleaned up the script tags and used the JQuery library from the Google AJAX Libraries site.

  9. //<!--
  11. $(function(){
  12. $('#cropbox').Jcrop({
  13. aspectRatio: 1,
  14. onSelect: updateCoords
  15. });
  16. });
  18. function updateCoords(c)
  19. {
  20. $('#x').val(c.x);
  21. $('#y').val(c.y);
  22. $('#w').val(c.w);
  23. $('#h').val(c.h);
  24. };
  26. function checkCoords()
  27. {
  28. if (parseInt($('#w').val())) return true;
  29. alert('Please select a crop region then press submit.');
  30. return false;
  31. };
  32. // -->
  37. Jcrop - Crop Behavior

This also includes the JCrop file (jquery.Jcrop.pack.js) and a CSS file (called jquery.Jcrop.css) that will make the selection box on the image look nice.

The function updateCoords() is used by JCrop to enter the coordinates of our crop into a set of hidden input boxes. This allows us to use a POST request to send the coordinates to our server. This is a callback function set in the JCrop initialization.

The aspectRatio setting forces the cropping box created to be square.

The checkCoords() function simply checks to see if a crop window has been created. If not then an alert is raised and the browser does nothing.

Next we need to implement our PHP code that will capture the image parameters and crop our image to a given size. This is done by creating an instance of the ImageManipulation class (giving the filename as the source), running the setCrop() method, with the correct parameters and using the show() method to display the output to screen.

  1. <?php if ($_SERVER['REQUEST_METHOD'] == 'POST')
  2. {
  3. $src = 'flowers.jpg';
  5. require('ImageManipulation.php');
  7. $objImage = new ImageManipulation($src);
  8. if ( $objImage-?>imageok ) {
  9. $objImage->setCrop($_POST['x'], $_POST['y'], $_POST['w'], $_POST['h']);
  10. $objImage->resize(500);
  11. $objImage->show();
  12. //$objImage->save('12345.png');
  13. } else {
  14. echo 'Error!';
  15. }
  16. exit;
  17. }
  18. ?>

This will display the output to screen only, if you want to save the output to a file then remove the comment on the line that runs the save() method.

I have put an example of this JCrop implementation in action in the same place as the ImageManipulation class. I have also created a source file so that you can download the full thing easily.

This method of cropping will work with any file type.



Hey, thanks for this code. It got me nearly there and I figured out the rest. One small fix - and one that you've probably already done since this post is two years old - you need to change the createResampledImage function code slightly in order to get an accurate crop. Otherwise it will always crop from the 0,0 mark of the original image.

Here is my fix:

private function createResampledImage()
  $this->image["des"] = ImageCreateTrueColor($this->image["sizex"], $this->image["sizey"]);
  imagecopyresampled($this->image["des"], $this->image["src"], 0, 0, $this->image["targetx"]*2, $this->image["targety"]*2, $this->image["sizex"], $this->image["sizey"], $this->image["sizex"], $this->image["sizey"]);  

Joshua Walcher (Tue, 10/25/2011 - 17:10)


Thanks for the fix Joshua. I honestly haven't looked at this post in a while (probably 2 years) but it's good to know it helped someone. The ImageManipulation class is getting a bit old now. I opened it up the other day for one reason or another and realised that it was a bit of a mess. It's not a very good class anyway as it doesn't allow the chaining of methods. I've come a long way since I wrote that! :) Still, it served its purpose at the time....

philipnorton42 (Tue, 10/25/2011 - 17:25)


thanks really really really thank you

when i done my work i will show you, cya ya

Valter Lorran (Fri, 01/27/2012 - 02:39)

Add new comment

The content of this field is kept private and will not be shown publicly.