21

I know there are thousands of jQuery plugins for image crop, but the one I need is similar to Facebook's image crop: a draggable fixed size square over a image, or a draggable image under a fixed size square.

I think there's a simple elegant code for it, instead of a 10k-50k framework for image manipulation that I'm finding everywhere.

KatieK
  • 13,586
  • 17
  • 76
  • 90

3 Answers3

15

I just built you a quick example of how to do it with jQuery: http://jsfiddle.net/gCqJ4/ It's not too hard and you can build off of my example. License is MIT.

There is a fundamental assumption being made here. First, your image is expected to already have been uploaded; this is just the crop part. Second, the image has a data-id attribute which specified the id of the image that the server can use.

I'll explain the JS a bit below:

First part is your typical jQuery plugin declaration:

(function($) {
    $.fn.croppable = function(settings) {

Then we take an optional argument of settings, with some sane defaults (success being your anonymous function for handling successful data submissions):

        settings = settings || {
            square: 50,
            default: 'middle',
            id: $(this).data("id"),
            success: null
        };

Next is just basic initial position calculation.

        var position = {
            x: settings.default == 'middle' ? ($(this).width() / 2) - (settings.square / 2) : 0 ,
            y: settings.default == 'middle' ? ($(this).height() / 2) - (settings.square / 2) : 0
        };

We wrap the image in a container that can be styled and used as the parent containment for the draggable cropper.

        $(this).wrap("<div class='croppable-container' style='position: relative;' />");

This is (obviously) the cropper.

        var cropper = $("<div style='position: absolute; top: " + position.y + "px; left: " + position.x + "px; height: " + settings.square + "px; width: " + settings.square + "px;' class='cropper' />");

Place it before the image:

        $(this).before(cropper);

Create a basic save button:

        var save = $("<input type='button' value='Crop Selection'/>");

And bind it to a service to receive posts for the cropping:

        save.click(function () {
           $.post("/your/service/location",
                  {
                      img: id,
                      x: cropper.position().left,
                      y: cropper.position().top,
                      height: settings.square
                  },
                  function (data) {
                      if (settings.success != null) {
                          settings.success(data);
                      }
                  }
            );
        });

        $(this).parent().width($(this).width());
        $(this).parent().height($(this).height());
        cropper.draggable({containment: "parent"});

        $(this).parent().after(save);

End of the typical plugin declaration:

    };
})(jQuery);

Call it:

$(".croppable").croppable();

As a final note, the plugin itself is only 1.61 KB. Small enough?

CassOnMars
  • 6,153
  • 2
  • 32
  • 47
  • 1
    Hey, thank you very much. Its exactly what I need, and its why I love stackoverflow so much. I ll keep your credits in the script and send you a link with the concrete use and credits. Thank you again. PS: 1.61 KB will get smaller after a minifier. =p –  Oct 21 '11 at 17:42
  • Could you please check the filddle link you gave , the crop part is not working . Thank You – Bujji Jun 04 '13 at 20:03
  • I'm not sure what you mean by the crop part not working; it's supposed to send data via AJAX with the requested crop coordinates, but you need a service to receive it. – CassOnMars Jun 05 '13 at 13:15
  • sorry . It was my bad . I don't know why I was expecting the square in the middle to re size and after clicking on crop checking next to it for the thumbnail without checking your code:) . Thanks for your comment and +1 for your code . One more mistake what I did was I didn't put Jquery UI JS in the path . I downloaded only drag-able component from it and it looks OK . Thanks for it again – Bujji Jun 05 '13 at 14:33
  • 1
    This is a nice solution, but it's not very small. The plugin is 1.6kb, but it requires jQuery UI's draggable, which is 32kb. That's 32kb for a custom download of only the draggable component of jQuery UI, and compressed. I've written a plugin for this that's only 4kb, compressed: https://github.com/tybro0103/jWindowCrop. It also includes zooming, which could be removed for yet less space. – tybro0103 Aug 02 '13 at 14:50
  • This is a fair point, although given the question, it looks like jQuery was already included in the project, so for additional size, it's less impactful. – CassOnMars Aug 02 '13 at 15:57
  • @tybro0103 : Thank you so much for the plugin!! You made a great plugin! – Sankalp Singha Feb 04 '14 at 07:59
  • @SankalpSingha Thanks, I wish I had time to maintain it! – tybro0103 Feb 04 '14 at 15:50
  • jWindowCrop - I need to send cropped image to API. How I can do this when I click on save button as in Facebook cover image. – Pradeep Jun 18 '23 at 10:28
4

I use imgAreaSelect. It's a great tool and very easy inputs and outputs...

To elaborate:

You can set the width, height and set the "resizable" option to false to achieve allowing the user to select a specific square (although normally I give users more freedom and crop the image when they select a different size - only enforcing the aspect ration.

Granted, this is 35Kb which can be minified to < 14kb. If you want it smaller I'd suggest stripping out some of the functions you don't need before you minify it.

Timbo
  • 4,505
  • 2
  • 26
  • 29
  • 2
    [Size = 55K](http://plugins.jquery.com/project/imgAreaSelect) – George Cummins Oct 21 '11 at 14:17
  • 1
    Actually it's 91KB, the ZIP contains packed, minified and development JS files. – MacMac Oct 21 '11 at 14:24
  • Here comes my point, added as a comment in my post, I dont need the functionality to let the user draw a square. I just simple need a premade square to be draggable around. Maybe someone have a library for it. Thx anyway. –  Oct 21 '11 at 14:29
  • What you're talking about is very simple with jQuery. You simply have an absolutely positioned div (the box) that moves around on mousedown and mousemove. Because of how simple the solution would be, I doubt anyone has written a library for it. – maxedison Oct 21 '11 at 14:41
  • Fair points re the size. Edited. – Timbo Oct 21 '11 at 14:55
  • Hey! Thank you for the edit Timbo. Ill sure learn something with that. –  Oct 21 '11 at 17:37
2

There are plenty jQuery plugins for client-side cropping (jCrop, imgAreaSelect, etc.). Maybe you will find the following blog post useful. It describes a solution for the actual cropping on the server while integrating with the Javascript libraries:

http://cloudinary.com/blog/cloudinary_as_the_server_side_for_javascript_image_cropping_libraries

Cloudinary
  • 541
  • 3
  • 4
  • This link is included in the blog, it is very helpful, so I think it deserves a comment. http://deepliquid.com/content/Jcrop.html There are some very good demos there of what it can do. – John Jun 20 '12 at 18:02