Details
| Version | 1.2.1 |
|---|---|
| Last updated | 6th October 2009 |
| Requirements |
|
| Demo | View demo page |
| Links | |
| License | BSD License |
| Changelog |
|
About
The JavaScript image cropper UI allows the user to crop an image using an interface with the same features and styling as found in commercial image editing software, and is is based on the Prototype JavaScript framework and script.aculo.us.
Initially I performed quite a lot of searching for some ready made solutions to meet my requirements, but found none that had the complete feature set that I required or any complete versions based on Prototype.
So after a week and a half of work, I present the JavaScript image cropper UI, built on Prototype & script.aculo.us.
Features
![]()
- Un-obtrusive
- Based on Prototype and script.aculo.us
- Image editing package styling & functionality, the crop area functions and looks like those found in popular image editing software
- Dynamic inclusion of required styles
- Drag to draw areas
- Shift drag to draw/resize areas as squares
- Selection area can be moved
- Selection area can be resized using resize handles
- Allows dimension ratio limited crop areas
- Allows minimum dimension crop areas
- Allows maximum dimensions crop areas, if both min & max set as the same value then we'll get a fixed cropper size on the axes as appropriate and the resize handles will not be displayed as appropriate
- Allows dynamic preview of resultant crop (if minimum width & height are provided), this is implemented as a subclass so can be removed if not required
- Movement of selection area by arrow keys (shift + arrow key will move selection area by 10 pixels)
- All operations stay within bounds of image
- All functionality & display compatible with most popular browsers supported by Prototype, tested in:
- PC: IE 6 & 5.5, Firefox 1.5, Opera 8.5 (see known issues) & 9.0b
- MAC: Camino 1.0, Firefox 1.5, Safari 2.0
Usage
Extract to a directory of your choosing e.g. 'scripts/cropper/' and include the script and the required Prototype & script.aculo.us scripts:
-
<script type="text/javascript" src="scripts/cropper/lib/prototype.js" language="javascript"></script>
-
<script type="text/javascript" src="scripts/cropper/lib/scriptaculous.js?load=effects,builder,dragdrop" language="javascript"></script>
-
<script type="text/javascript" src="scripts/cropper/cropper.js" language="javascript"></script>
Options
- ratioDim obj
- The pixel dimensions to apply as a restrictive ratio, with properties x & y.
- minWidth int
- The minimum width for the select area in pixels.
- minHeight int
- The mimimum height for the select area in pixels.
- maxWidth int
- The maximum width for the select areas in pixels (if both minWidth & maxWidth set to same the width of the cropper will be fixed)
- maxHeight int
- The maximum height for the select areas in pixels (if both minHeight & maxHeight set to same the height of the cropper will be fixed)
- displayOnInit int
- Whether to display the select area on initialisation, only used when providing minimum width & height or ratio.
- onEndCrop func
- The callback function to provide the crop details to on end of a crop.
- captureKeys boolean
- Whether to capture the keys for moving the select area, as these can cause some problems at the moment.
- onloadCoords obj
- A coordinates object with properties x1, y1, x2 & y2; for the coordinates of the select area to display onload
The callback function
The callback function is a function that allows you to capture the crop co-ordinates when the user finished a crop movement, it is passed two arguments:
- coords, obj, coordinates object with properties x1, y1, x2 & y2; for the coordinates of the select area.
- dimensions, obj, dimensions object with properities width & height; for the dimensions of the select area.
An example function which outputs the crop values to form fields:
-
function onEndCrop( coords, dimensions ) {
-
$( 'x1' ).value = coords.x1;
-
$( 'y1' ).value = coords.y1;
-
$( 'x2' ).value = coords.x2;
-
$( 'y2' ).value = coords.y2;
-
$( 'width' ).value = dimensions.width;
-
$( 'height' ).value = dimensions.height;
-
}
Basic interface
This basic example will attach the cropper UI to the test image and return crop results to the provided callback function.
Minimum dimensions
You can apply minimum dimensions to a single axis or both, this example applies minimum dimensions to both axis.
Select area ratio
You can apply a ratio to the selection area, this example applies a 4:3 ratio to the select area.
-
<img src="test.jpg" alt="Test image" id="testImage" width="500" height="333" />
-
-
<script type="text/javascript" language="javascript">
-
Event.observe( window, 'load', function() {
-
new Cropper.Img(
-
'testImage',
-
{
-
ratioDim: {
-
x: 220,
-
y: 165
-
},
-
displayOnInit: true,
-
onEndCrop: onEndCrop
-
}
-
);
-
} );
-
</script>
With crop preview
You can display a dynamically produced preview of the resulting crop by using the ImgWithPreview subclass, a preview can only be displayed when we have a fixed size (set via minWidth & minHeight options). Note that the displayOnInit option is not required as this is the default behaviour when displaying a crop preview.
-
<img src="test.jpg" alt="Test image" id="testImage" width="500" height="333" />
-
<div id="previewWrap"></div>
-
-
<script type="text/javascript" language="javascript">
-
Event.observe( window, 'load', function() {
-
new Cropper.ImgWithPreview(
-
'testImage',
-
{
-
previewWrap: 'previewWrap',
-
minWidth: 120,
-
minHeight: 120,
-
ratioDim: { x: 200, y: 120 },
-
onEndCrop: onEndCrop
-
}
-
);
-
} );
-
</script>
Known Issues
- Safari animated gifs, only one of each will animate, this seems to be a known Safari issue.
- After drawing an area and then clicking to start a new drag in IE 5.5 the rendered height appears as the last height until the user drags, this appears to be the related to another IE error (which has been fixed) where IE does not always redraw the select area properly.
- Lack of CSS opacity support in Opera before version 9 mean we disable those style rules, if Opera 8 support is important you & you want the overlay to work then you can use the Opera rules in the CSS to apply a black PNG with 50% alpha transparency to replicate the effect.
- Styling & borders on image, any CSS styling applied directly to the image itself (floats, borders, padding, margin, etc.) will cause problems with the cropper. The use of a wrapper element to apply these styles to is recommended.
- overflow: auto or overflow: scroll on parent will cause cropper to burst out of parent in IE and Opera when applied (maybe Mac browsers too) I'm not sure why yet.
SEO Agency advanced JavaScript experience can enhance your site functionality. Adding the JavaScript Image Cropper is a good way to improve the user experience.
Next Steps
Feature Requests & Bug Reports
Please check the existing list of feature requests & bugs and the discussion list before posting requests or reporting bugs.
Leave a Tip
If you find this code useful you can leave a donation towards the continued development & support.
Comments
There have been 699 comments so far, join the discussion.
Pages: « 1 … 4 5 6 7 8 [9] 10 11 12 13 14 » Show All
401. acctman - 5th Dec 2007 - 6:10 pm
does anyone have a working example of how to upload and image crop and save the image?
402. wozzzzza - 5th Dec 2007 - 9:11 pm
acctman, go here. http://mondaybynoon.com/2007/01/22/crop-resize-with-javascript-PHP-and-imagemagick/
403. Quessir - 6th Dec 2007 - 10:18 am
Hi, David. Your cropper works excellent on Firefox(2.0.0.11)... But absolutely doesn’t in IE (neither 6, nor 7) and Opera(9.10). I don’t know why, ‘cause i saw examples and demos. I did it almost the same way. Maybe, the reason is it coded on Prototype 1.5.0 and i’m using 1.6. Is there any updates for 1.6?
404. Ionut - 7th Dec 2007 - 10:21 am
Hello!
Does anybody knows how to control(move/resize) the cropping selection programatically, using some buttons for exemple?
Thanks
405. Chris - 7th Dec 2007 - 11:37 am
I just couldn’t resist replying to this post. I mean, someone has taken the time to write a working model of code and yet someone is too lazy to figure out the rest of it on their own. They want to be spoon fed!
“Does anybody knows how to control(move/resize) the cropping selection programatically, using some buttons for exemple?”
I would recommend reading “JavaScript for Dummies” instead of just asking a question like this. Also, you might want to pick up a dictionary at the same time to take advantage of combined shipping to help reduce the cost of shipping. Alternatively, you could hire a web developer to do the work for you.
JavaScript for Dummies: http://www.amazon.com/JavaScript-Dummies-Emily-Vander-Veer/dp/0764576593/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1197024961&sr=8-1
406. Ionut - 7th Dec 2007 - 12:07 pm
To Chris:
“Thanks man your advice is very useful…”
407. Chris - 7th Dec 2007 - 1:34 pm
To Ionut:
Not trying to personally insult you, but in the world of developers…be prepared to carry your own weight or face criticism.
408. shovavnik - 7th Dec 2007 - 4:39 pm
To Chris:
1. Not everybody is as experienced as you seem to be. Some are starting off. Some are knowledgeable in other areas.
2. Not everybody speaks English as a native tongue. Maybe you could offer to buy them a dictionary and save them the shipping altogether.
3. Your jive talks and quacks like a personal insult, whatever you say.
4. Why exactly couldn’t you “resist”? Whose fault is that? I don’t know when you joined the list, but you certainly managed to “resist” on the dozens of requests for assistance before this last one.
A programmer may have to carry his/her own weight. (And maybe this guy’s just starting out?) But a person has to carry more than just his weight on his shoulders.
409. Chris - 7th Dec 2007 - 6:12 pm
To shovavnik:
I’ve had my share of slaps in the face when I first started. Did I let that discourage me from trying? No, I pressed on to find the answers.
But to get back on track on why I posted a comment to begin with after seeing several similar posts….if someone has taken their time to make something available for free and only ask for a voluntary donation, what else do you want? I’m just saying if you are going to take someone else’s work for free and use it, don’t expect it to be gift wrapped.
410. ionut - 8th Dec 2007 - 2:19 am
Hello!
In the end I manage to find the answer by myself… the reason I ask that question was to see if someone else had the same issue and how they manage to fix it… I believe that this is the reason we have forums … to cooperate and to make things better together.
411. Johan Höglund - 10th Dec 2007 - 1:53 am
There seems to be a problem with cropper and jquery.
If i load both jquery and cropper on the same page, the cropper doesn’t work.
I’m using Firefox 2, i load the scripts in this order:
prototype
scriptaculous
cropper
jquery
I do not use any of the jquery functions/classes.
I’ve added an alert window at line #238 (Inside Cropper.Img.prototype, in the initialize: function)
The alert window pops ups, so at least that line is run.
Firefox does not generate any error message or warning, just dead nothing.
What happens is that the image is left untouched, no special cursor, no resizable area, just an ordninary image.
412. usha - 10th Dec 2007 - 8:27 am
How to save the cropped image?Please help me?Its very urgent.
Thanks,
Usha
413. Dave - 10th Dec 2007 - 9:00 am
Johan:
I’ve never really looked at jquery before, but my first guess would be is it defining any global functions/classes/objects that have the same name as any prototype/script.aculo.us, e.g. the $() function etc. As you’re loading in jquery last then if it does they would override the previous definitions.
414. TK - 19th Dec 2007 - 7:21 am
Would be much better if we make it able to select circle-areas or include a magic-wand feature like photoshop…but right now, I think this is the best we can get~
415. wozzzzza - 19th Dec 2007 - 9:40 pm
@TK
yeah why dont we just upload photoshop to our websites and make each user who wants to crop anything download 500meg each time, that would be just as effective as what you want to do. or better still provide a remote desktop link to your computer on their website where a user can upload a pic to your computer, open photoshop and then modify it that way hey??
416. Mert - 20th Dec 2007 - 11:30 am
Hey, how can I cancel the cropping after selecting a portion on the image?
(rolling-back the visual to its initial state)
Thx..
417. madchimp - 23rd Dec 2007 - 3:14 pm
Very sweet script I can’t wait to start palying with it on my site. It is exactly what i was looking for! Once I have it implemented on my wifes site she should be able to upload the pictures on her own. heheh A big thanks for making your code available to the community
418. Dave - 24th Dec 2007 - 3:42 pm
Madchimp:
Thanks for the kind comments, I’m glad you found it useful.
419. Dave - 24th Dec 2007 - 3:47 pm
This is just a quick note to all those who have left comments and are interested in the progress of the JavaScript image cropper, I have just posted a quick overview of my plans for the next version of the cropper.
So if you’re interested in finding out about my plans for the next version and how you can help then I urge you to read my post on JavaScript Image Cropper V2 Details and Fund Raising
420. Leonardo Diaz - 7th Jan 2008 - 3:51 am
Hi, this is a great work, unfortunately it does not work using scriptaculous version 1.7. It seems that it works with no problem “no matter” the version of prototype, but the version for scriptaculous has to be 1.6.
It gives 2 errors (using firebug)
1. Class is not defined
[Break on this error] var CropDraggable=Class.create();
cropper.js (line 18)
2. Cropper has no properties
(no name)()update (line 50)
[Break on this error] new Cropper.ImgWithPreview(
The same error occurs, when you dont load the scriptaculous library, so that is a starting point
421. Leonardo Diaz - 7th Jan 2008 - 5:24 am
Forget what I comment bellow, I was trying using Symfony, and I forgot to load the cropper library AFTER scriptaculous. ;P
Sorry…. ANd this library ROCKS!!!
422. j snod - 11th Jan 2008 - 8:29 pm
How do I make ratioDim optional when instantiating a Cropper.ImgWithPreview object? If I do it like this:
ratioDim: { x: 0, y: 0}
...or remove the ratioDim declaration completely from the Cropper.ImgWithPreview call, I have to click the image TWICE to get the cropper. First click shows the preview, 2nd click enables the cropper. How can I make an Cropper.ImgWithPreview object without using ratioDim ?
423. j snod - 11th Jan 2008 - 9:11 pm
Just to clarify my previous comment, I want to set a minWidth and minHeight but NOT constrain the proportions, like so:
Leaving out ratioDim doesn’t seem to work. Is it required?
424. j snod - 11th Jan 2008 - 9:12 pm
Ummm.. . crap.. ignore my code sample. :(
425. Dave - 11th Jan 2008 - 9:16 pm
j snod:
Yes the ratioDim is required if you are using the preview version, this is because the preview script uses that to create a fixed size preview. You should be able to remove that from the code for the preview version (I think someone else has already done that in the comments somewhere). I’ve added this as a enhancement request (00030).
426. Anders Jenbo - 12th Jan 2008 - 2:41 pm
Hmm i don’t see how i can add feature requests or bug reports, so I’m just going to post it as a comment.
Heres and alternate attachCropper function for example-DynamicImage.html that will allow you to load the crop area that you had before you removed it and even enter it in the input and then load it. It makes it allot more usefull if you want to have other tools then just crop and don’t want to start over on the selection each time you have made some other adjustments to the image.
427. Luke - 14th Jan 2008 - 4:03 am
This might be a cousin of 00027 but when I had the cropper image inside a hidden div, clicked the ‘Remake Thumb’ tab to show it, it wouldn’t work. I was previously using an HTML Component and then I found this little gem and was super excited to update my photo gallery and have it work in FF as well. I still works beautifully, I just can’t have it in a hidden div.
Anywayz, regardless of the hidden div issue, this is an awesome script. Kudos/Many thanks to Dave. People like him make the Internet great.
428. David - 24th Jan 2008 - 9:25 pm
Hello,
This is great work.
The only problem i have is that when a click happens anywhere in the page i put the crop script, its launching the callback function.
I saw that the mouse release event was the trigger in the code.
Is there a way to make that mouse release/click only calling the function when the mouse is over the image and not aywhere in the page ?
Thanks a lot.
David.
429. paul - 5th Feb 2008 - 11:56 pm
Great script—we need the highlighted crop area to save to the server using PHP (to pass to GD libary)... anyone have any examples using this js with PHP? we’re at the point where the crop tool captures the coords, but how do we capture the ouput, to pass to the gd library, to resize? thanks! paul
430. Matt Barnicle - 6th Feb 2008 - 2:19 am
@paul
I created a proof of concept for a client with a specific feature set requirements. I implemented a backend PHP script to do the uploading, cropping and saving. Recently another user emailed me for a copy of the code and I zipped it up for him. I’m happy to make this available to anyone who wants to download it… You can read about my specific implementation in this series of posts:
http://www.defusion.org.uk/code/javascript-image-cropper-ui-using-prototype-scriptaculous/comment-page-9/#comment-27233
You can download a zip file of all the code (js and PHP) here:
http://gattomatto.net/work/jsCropperUI.zip
Please be aware however, this code was only build as a proof of concept, and never made it into their web site. As such the code is a bit sloppy.. But it is all there, and anyone with reasonable PHP skills will be able to take this code and work it into something more robust. And if you or anyone does that, I encourage you to post a link to your results… I’d like to get a copy of that myself!
Thanks,
– m@
431. John - 7th Feb 2008 - 8:00 am
Hi. I realy like the work you have done, and I’m trying to use it in my site but facing this problem (only in IE and not in FireFox):
1) I’m dynamically changing the main picture the user can work with (by clicking on a strip of thumbnails).
2) when such a change occures, I set the HTML ID of the selected image to be “theMainPicture”.
3) I also create a new instance of the Cropper object: new Cropper.Img( ‘theMainPicture’, { onEndCrop: onEndCrop }
4) All is working fine for the first selection but when user is choosing a different image, he can select areas on it, but the X & Y coordinates are always the ones of the first selection.
Can you help please?
432. Dave - 7th Feb 2008 - 10:51 am
*@John:*
Check out the “Dynamically changing image” demo on the demos page (or test/example-DynamicImage.htm in the download) for an example on how to change the image for the cropper dynamically at runtime.
433. John - 7th Feb 2008 - 1:29 pm
Hello Dave.
When I tried to implement the “dynamic” example, I got this error:
“Event.observe is not a function”
Any ideas?
434. Micheal Hall - 9th Feb 2008 - 3:20 am
Hi,
I just wanted to express my gratitude for this tool. It’s EXACTLY what I have been looking for for some time now.
I’ve successfully integrated it into our web based photography display/design/ordering system and am translating its output for use on full resolution files in our production system. Having this available will have dramatically positive impacts on the time it takes to produce our orders. (Not to mention how much fun our customers are having using this and seeing precropped images in their collage previews).
You’ve just saved us a great deal of time and potentially boosted sales- thank you!
Regards,
Micheal
435. TheIceman5 - 9th Feb 2008 - 3:23 am
@Micheal Hall,
if thats the case you wont mind donating to the author of this cool script, that way he might get a new version up and running for us all before we retire in 30 years. just click the donate button somewhere on this site.
436. Dave - 9th Feb 2008 - 2:24 pm
*@Michael Hall:*
Thanks for the comments, I’m really glad it worked out and helped you, also thanks for the donation.
*@TheIceman5:*
I sense a little frustration in your comment there, I am hoping to get started on the V2 script soon – I just need to get my current project out of the way (and having been ill for the best part of a month hasn’t helped with that). I do want to get a V2 out there as soon as possible – I appreciate the support that the fund-raising has seen for V2 (and I’m also glad it has continued after the first few days I was worried that no-one was interested).
I’ll make sure V2 is well worth the wait.
437. DevNow - 12th Feb 2008 - 8:34 pm
Is it possible to quickly modify the existing code to work with Prototype 1.6 and Scriptaculous 1.8? A new site I am working on is built on the latest versions of Prototype and Scriptaculous and everything is great, but when I go to integrate the Image Cropper I get nowhere. Various errors are reported, but I am not real sure where to go for troubleshooting. Any chance you can quickly see why the Cropper doesn’t work with the latest and greatest? It works as intended with the older versions, but when you just switch to the new version of code the Cropper fails. We regularly donate to sites and outfits who provide us with solutions.
438. Dave - 12th Feb 2008 - 9:03 pm
DevNow:
I’ve just tried including the latest versions of prototype & scriptaculous in the basic test & with preview test (found in the tests directory) and I get no errors (in Firefox).
439. Micheal Hall - 13th Feb 2008 - 2:18 am
@TheIceMan5
You’re absolutely right – I donated before I posted my appreciation for the tool.
@Dave
You’re welcome, I really appreciate that you created this tool and made it available. I’m watching our production system churn its way through orders right now – I’ve photographed three events since I first implemented your UICropper and it has really made a difference in the customer’s experience. For us as photographers, being able crop images as we layout collages on the screen in front of the customer makes a substantial difference – they can now see more clearly what we see when we look at the images and it allows them to purchase with more confidence in what they will be receiving. You should hear the ‘ooohs’ and ‘aaahs’. :)
Great stuff!
Regards,
~Micheal
440. StAT - 19th Feb 2008 - 3:03 pm
Thank you! Great script.
There is little bug(?) when using with IE7 without HTML 4.01 Transitional in quirk mode. I was forced to remove standart course multitr table height100% bug in IE.
It can be “fixed” with this:
.imgCrop_overlay {
background: URL(semitrblack.gif) fixed;
/* opacity: 0.5;
filter:alpha(opacity=50);*/
position: absolute;
width: 100%;
height: 100%;
}
where semitrblack.gif is semitransparent gif image.
And sorry for mein englendo language. ))))
441. StAT - 19th Feb 2008 - 6:08 pm
And there was little problem with absolutly white image. After refresh of the page everything is ok. But with new image for crop the same picture. Fixed with:
.imgCrop_handle {
position: absolute;
border: 1px solid #333;
width: 6px;
height: 6px;
background: URL(tr.gif) fixed;
opacity: 0.5;
filter:alpha(opacity=50);
z-index: 4;
}
I don’t know. May be this problems mine only.
FF and Opera work ok.
442. Brent O'Connor - 21st Feb 2008 - 9:06 pm
Awesome job! This is exactly what I was looking for. I only wish you had a jQuery version.
443. Dave - 21st Feb 2008 - 11:23 pm
*@Brent:*
I’m glad you liked it. There are plans to do a jQuery (and other frameworks) version (see the V2 plans linked to on the post), but I’m totally snowed under with other projects at the moment.
444. Christophe - 26th Feb 2008 - 4:36 pm
Hi, very nicely done
But I have a question though. Do you keep track of all the area’s that get highlighted? I tried to use the script in combination with an ajax script that loads the image.
When the image is loaded, I call a method to initialize the events. I got that working. When I select an area and onEndCrop is loaded, I reload the image via the server (It’s a map where I try to zoom in).
But here it goes wrong. When I do it again, the script is called twice, with the coordinates from the first time and the ones from now.
I tried a lot, but could not find a solution.
Thanks anyway
445. Dave - 8th Mar 2008 - 12:27 am
Hi i would like know if it’s possible disable the resize option. I need to pass coords on load, but without resize the crop. Is it possible?
Tks a lot! ;-)
446. Dave - 8th Mar 2008 - 10:02 am
*@Dave:*
If you pass both the min and max co-ords and set them both to the same values then the user won’t be able to resize (and the resize handles will not be displayed).
447. Paul - 9th Mar 2008 - 7:17 pm
If I get this doing what I need it to in my project, I’m donating..
Looks great.. thanks
448. Jimmy - 18th Mar 2008 - 3:41 pm
I almost have this wonderful tool doing magic… the only problem is that no matter what I do, I can’t seem to remove the onEndCrop co-ordinates/dimensions from images once they’re removed from the DOM. In other words, once I’ve loaded a second image called with an ID the same as the first (though the first is removed from the DOM) I get all the old dimensions followed by the new ones when onEndCrop is called; I think this is the same thing that is referred to in the comments in the script as ”#00015” (onEndCrop callback gets called multiple times when removed and then reapplied). Everything on my page is pretty AJAX-y, and I simply cannot get the my cropper to remove() itself. I’ve looked at the dynamic-image example but can’t grok it; my case is pretty different. Tips??? THANKS!
449. Dave - 18th Mar 2008 - 4:03 pm
Jimmy:
A link to an example of your implementation would be helpful – or details on how you’re removing/re-adding the cropper if you’re not using the same technique as in the dynamic image example.
450. Jimmy - 18th Mar 2008 - 4:54 pm
Hi, I appreciate your help. I’m really just calling each one with this:
“new Cropper.Img(theImageID, { onEndCrop: onEndCrop });”
I’m then removing a DOM node that contains my image and all the new nodes created by Cropper, and then recreating the node and the various bare images in it, and applying the above line for each image ID.
I have changed the onEndCrop function in your cropper.js to return the ID its referring to (in addition to the coordinates/dimensions), so I can keep track of the co-ordinates of more than one image at a time…
I’d use the example if I could, I just can’t seem to find a way to get my varying imageIDs into the “new Cropper.Img” call in attachCropper…. I must seem silly but I feel I’m so close, and there are other people on this forum who also seem to long for a way to easily remove the cropper…. I see the “remove:function()” in “cropper.js”, if only I could pass my imageID to it!!
Leave a comment
No HTML please, only textile. For code please use [lang]...[/lang] tags (e.g. [html]...[/html] for HTML)