Uvumi Tools

UvumiTools Crop

spacer

Click mask: Move resizer to that position
Shift + Resize: Keep current selection's aspect ratio if not enabled by default
Doubleclick on resizer: Maximize selection

Description

As the web grows and becomes more dynamic ("Web 2.0"), more and more websites have user-generated content and boast tools to let users sumbit text, images, videos, and more, providing content for entire web networks. Most of the time, people submit photos straight from their camera because they don't have photo editing programs or they don't know how to use them. This simplified tool gives your users the ability to create a selection area that can be used to crop an image live on your web site. This is an extremely useful too for any site that provides image hosting, for example.

Features

  • NEW! From simple to advanced: In our first version of UvumiTools Crop, we bragged about how simple and easy it was, but the community wanted more advanced functionality. It was too simple and lacked some features other cropping tools offered. We listened to you and started work on a more sophisticated version. But we also like having the option of simplicity. So we decided that any new advanced feature would be optional and can be switched on or off easily. Now, you can configure the cropper to be as simple as before, or you can turn it into one of the most advanced free image cropping tools available.
  • Set minimum sizes: If you know the thumbnails on your website will be 120*90 pixels, just set those values as minimums, and your users won't be able to select any smaller area than this. Why? Because if a smaller area is submitted, you have three potential outcomes:
    • The cropped image may not fill containers designed for a specific size.
    • The server script will automatically expand the area before cropping to match the minimum size, surprising the user with a thumbnail not matching what was actually selected.
    • The server script will crop the image to this smaller size first, then resize the thumb by stretching it to the minimum size, resulting in image quality loss, especially if the user selected a very small area.
    By defining a minimum size, you can avoid these problems.
  • Keep aspect ratio (or not): If you want all the thumbnails on your website to be squared or 4:3 and nothing else, you can lock the aspect ratio to the dimensions you specified as minimums (see above). The selection's height and width will grow and shrink together, maintaining proportions. NEW: Now you can disable the forced aspect ratio option, but users can still maintain it on demand by holding the Shift key when resizing.
  • Real time preview: You can set an element of your document to render a preview of the thumbnail. It might not look as good as an actual resampled image, but it definitely gives your users a good idea of what the resulting image will look like. NEW: Now the preview can be displayed directly over the image instead of inside an element. The preview will be displayed in a small box which follows the selection. No need for reserved space in the document anymore. You can still use the old fashioned way if you want.
  • Support HTML resizing: If the image has been resized to fit in the document, with <img> WIDTH and HEIGHT attributes or with CSS, the script will detect it and still return correct coordinates.
  • Callback function: This feature is very important, because without it this tool would be useless. Making selections on top of a image is fun, but if you can't do anything with it, what's the point? Once you've created a selection, you must communicate the coordinates to your server-side script so it can perform the actual crop. It will need need two pieces of data: position and dimensions. That's why the cropper has a callback function, fired after every drag on the selection. By default, this function does absolutly nothing, but you can set it do anything when you initialize the script. The callback function recieves four arguments: top, left, width, height. It's up to you to grab those values, and put them in a form to submit to the server-side script. The demo shows how to do that. Ideally you would put them into hidden inputs, with another one referencing the image file to be cropped.
  • Can be toggled on and off: UvumiTools Crop offers tools to completly remove itself from the document (ideal once the the coordinates have been submited to the server) or to hide it so you can show it again later, without regenerating a new one. Good for memory management.
  • Modify style with CSS: Style is not hard-coded--you can modify the mask's color, the selection's border color, its thickness and style, with basic CSS. Use the downloadable sample to get started. Some important properties are overwritten by javscript to ensure the script will work, but they don't affect the way it looks. There isn't much you want to modifiy beside the mask and the border colors anyway.
  • Fast, even on slow computers: This one is for advanced CSS users: the other cropping scripts I've seen use a four-DIVs trick to display a mask around the selection. And that's how we initially coded ours--Everytime the selection is moved or resized we had to recalculate the positions and dimentions of the four Div elements. That meant 4 css properties for each div, except the first one which always stayed in the top left corner. But that's still 14 properties to calculate and update on every mouse move. If you add the preview at the same time, it can slow things down a bit.

    Then we found a blog article about the little-known CSS cliping property. It almost does what this mask does: you specify four coordinates within an element (top, right, bottom, left) and it only renders this area, everything else is masked out. It took us a while to figure how to use it in the cropper context, because at first it was doing the opposite of what we wanted: it was rendering the mask only inside the selection, not outside. So in the end we duplicated the image, and superimposed everything in four layers from bottom to top: original image, mask, image clone, selection. Then we applied the clipping property on the image clone, while keeping the mask as a single div covering the original. Now when modifiying the selection, all we do is update the clip property on the image clone--just one CSS property to update instead of fourteen.
  • Change image inside the Cropper on the fly: We got several questions in the forum asking how to change the image source without breaking the cropper (the image would update but the cropper would still "think" it's dealing with the old one). We never really thought about this possibility and the cropper was not designed support it. With a little bit of extra work we have been able to whip up a special function to take car of this. Just pass the url to the new image, and that's it.
  • New! From 0 to 8 resizing handles: You can decide which resizing handles should be displayed. You can have only one in a corner, like the old school UvumiCrop, or you can have one in each corner, or one on each side or all of them or even weird combinations or three or five handles. It's in your hands now, just pass an array of handles to the script and it will only generate those.
  • New! Maximize selection on double-click: You already know you want to select the biggest area possible? No problem, just double click in the middle of the selection and it will automatically expand to its maximum size. If there is no proportion constraint, it will simply select the entire image, else it will create the biggest selection with those proportions that can fit in the image.
  • New! Edit the selection dimensions and position with text inputs: UvumiTools Crop now offers a multi-function box which follows the selection on the image. This box contains four text inputs to edit the top, left, width and height values of the selection. You can see those values being updated automatically as you move or resize the selection. But it also works the other way: you can modify those values and see the selection being updated. The script makes sure the typed in values are valid, and maintains the aspect ratio if necessary. This is useful for advanced users who know exactly what size they want the image to be. This box can be styled with CSS.
  • NEW! BUILT-IN SERVER SIDE CROPPING SCRIPT: Awww yeah. UvumiTools Crop used to come with a PHP sample script to crop the image. But some of you had some trouble to make it work with the client side cropper. Now you get two PHP scripts which can be called directly from the javascript object. One script generates the thumb and returns the image for direct download, while the other one, for advanced users, saves it into a designated folder. Using those scripts is as simple as calling the cropSave() or cropDownload() functions. No more missing parameters or wrong input names, everything is taken care of. All you need to do is make sure the image path in the script matches the one on you site, that's all. You can even set a callback function for the saving script, to execute once the thumbnail has been generated (advanced users). Even better, you can add a Download and Save button directly into the coordinate box described in the previous point, it just takes one option. Oh, the cropping script handles file formats and keep trnasparency in GIF and PNG files. *Requires GD Library for PHP

Requirements

What you'll need:

  • A server-side script: Unlike other UvumiTools scripts which are mostly client-side only tools, UvumiTools Crop must be paired with a server-side script that will actually be able to so something with the coordinates. We are now providing two sample PHP scripts to crop images on the server side. They are available in the downloads section below.
  • Mootools 1.2: To use this plugin you'll need Mootools 1.2, but if you are already using another javascript framework like Prototype or JQuery, you may have to decide which one you want to keep because those frameworks were not designed to work together, and they ofen conflict with each other. Mootools might be a little heavy for only one plugin, but it's one of the best frameworks around, so it's a good occasion to start learning.

    And yes, you actually do need version 1.2 of Mootools. If you are already using a previous version of Mootools then the Crop will not work unless you upgrade. Sure, upgrading is a slight hassle, but trust us, it's worth it in the long run.
  • Mootools Dependencies: If your website already contains some Mootools 1.2 stuff (from this wesite or elsewhere), then you're stoked because you can use a single Mootools library for everything. All you'll need is the UvumiTools Crop script, and to make sure your library contains the following classes:

    • Core
      • Core
      • Browser
    • Native
      • Array
      • Function
      • Number
      • String
      • Hash
      • Event
    • Class
      • Class
      • Class.Extra
    • Element
      • Element
      • Element.Event
      • Element.Style
      • Element.Dimensions
    • Utilities
      • DomReady
      • JSON
    • Fx
      • Fx
      • FX.CSS
      • FX.Tween
    • Request
      • Request
      • Request.JSON
    • Plugins
      • Fx.Elements
      • Drag
      • Drag.Move
      • Assets

How To

Initialization

new uvumiCropper(image,options);

Arguments

  • Image: Can be the ID of an image HTML element, or the element it-self, if grabbed the mootools way with the $() function. If you don't understand what it means, just pass the image ID.
  • Options: an object that will allow you to modify some properties of the script. Options are optional (of course). If you just want to keep default value, you don't need this second parameter.

Options

  • maskOpacity: Number between 0 and 1, defining the opacity of the masked overlayed on top of the image. Default is 0.5. To change its color, use the attached CSS file. If set to 0 or false, the mask will simply not be generated at all.
  • maskClassName: The css class you want to be applied to the mask, to modify its style with css. Default is cropperMask which corresponds to the name used in the sample CSS file that comes with this plugin.
  • moverClassName: The css class you want to be applied to the middle area that lets you drag the cropping region. You shouldn't have to modify this style. Default is cropperMove which corresponds to the name used in the sample CSS file that comes with this plugin.
  • resizerClassName: The css class you want to be applied to the outter area of cropping region. If you want to overrride the default red dashed border, this is the class you will alter. Default is cropperResize which corresponds to the name used in the sample CSS file that comes with this plugin.
  • wrapperClassName: The css class you want to be applied to the image wrapper. You shouldn't have to modify this style. Default is cropperWrapper which corresponds to the name used in the sample CSS file that comes with this plugin.
  • handleClassName: Each handle receives this css class. this allows you to set common style for every hange. Default is cropperHandle. Then each handle receives extra classes corresponding to its possition: top, left, bottom, right. A corner will have two of those, while the sides one will have only one. Using those class you can set various background images and cursors to each handle.
  • coordinatesClassName: The coordinate input, the preview, and the save/download buttons can be displayed in a box which follows the selection over the image. This box can be styled and so can be its content (inputs, labels, buttons) thanks to this css class. Default is cropperCoordinates. See the attached css file to learn how to style the box elements.
  • mini: An object with two values, x and y, defining the size of the thumbnail. These coordinates are used to generate the preview and as minimum size for the cropping region. Default is {x:80,y:60}.
  • handles: An array of variable size. Each element correspond to a handle. An element can be 'top', 'left', 'right', 'bottom' or an array containing two of those. 'top' will generate a handle in the middle of the top segement, 'left' in the middle of the left segment and the ['top','left'] array will generate a handle in the top left corner. Default is [ ['top', 'left'], 'top', ['top', 'right'], 'right', 'left', ['bottom', 'left'], 'bottom', ['bottom', 'right'] ], which represents all the possible handles. If an empty array or false is passed, no handle will be generated, making the selection movable but not resizable.
  • onComplete: Event function fired when when you stop dragging/resizing. recieves four parameters: top, left, width, height (of the selection). By default, it's empty, but you can write a function to update a form that contains one hidden input for each coordinate (or one input with a json string, it's up to you). Then by submitting this form to a server script, you should be able to crop your image on the back-end (eg with GD library in PHP, just as we do in the sample script you can download below).
  • keepRatio: Boolean value, if the width/height ratio of the selection should be maintained or not. Default is false. When disabled, user can still lock the selection aspect ration by holding the Shift key while resizing. the user might not guess this feature, it will be your job to write some instructions.
  • doubleClick: by default, when the user double-clicks the selection, it expands to its maximum size. While this is a nice feature, we hought you might want to disable it for some reason. Default is true.
  • handleSize: Size of the handles in pixels. Default is 16, even if the images we used are 12 pixels big, because we thought it would be more user friendly to have a bigger draggable area.
  • coordinates: If the coordinate manual adjustment inputs should be displayed or not. Default is false.
  • preview: if you want to display a preview of the cropped image, you must specify a target container by its ID or true. Default is false, which means no preview will be generated. If anything is passed, the script will try to select the element with the corresponding ID. If it fails, it will display the preview in the coordinates box. In other words, if you only pass 'true' instead of an id.
  • downloadButton: If set to true, a button is added to the coordinates box to download the cropped image. Default is false. If a string is passed instead of true, it will be used as text for the button. If you pass an object, it will be passed as extra parameters to the download request.
  • saveButton: If set to true, a button is added to the coordinates box to save the cropped image on the server. Default is false. If a string is passed instead of true, it will be used as text for the button. If you pass an object, it will be passed as extra parameters to the save request.
  • cancelButton: If set to true, a button is added to the coordinates box to destroy the cropper. Default is false. If a string is passed instead of true, it will be used as text for the button.
  • adopt: You want to put something else than a preview or a submit button in the toolbox? it's possible: if you set this option with a string, a reference to an element or a collection of element, it will be injected in the box.
  • coordinatesOpacity: This coordinates box might be annoying when you are dragging the selection. That's why we offer to reduce it's opacity when not hovered. Default is 0.25 and it will automatically raise to 1 when the mouse hovers the box. Set it to false or 1 to disable this effect and leave the box allways fully visible.
  • serverScriptSave: The cropSave() performs an ajax request on a server side script. This script must be located, relatively to the document or absolutely thanks to this option. Default is 'save-thumb.php', which corresponds to the downloadable script.
  • serverScriptDownload: The cropDownload() function will call the download script. This script must be located, relatively to the document or absolutely thanks to this option. Default is 'download-thumb.php', which corresponds to the downloadable script.
  • parameters: If you already know which extra parameter you want to submit with the request when you create the cropper (an pointer to an image id in the database?), you can pass an object of parameter-value here. Default is an empty object{}. You can add parameters later thanks to a public function described next.
  • onRequestFail: This callback function is triggered when the save request fails, in case of unexpected error. By default the function just alerts a warning message.
  • onCropFail: This callback function is triggered when the save request fails on an expected error. By default the function just alerts a type of error.
  • onCropSuccess: This callback function is triggered when the save request is successful. By default the function just replaces the image with the new thumbnail. It will be your job to modify this function (and the server side script) to fit into your website architecture.
  • onDestroyed: Event function fired when the cropper is destroyed.

Public Functions

Yes, we know, there is no real private or public data javascript, but while most functions of the cropper are for internal use only, some were made to be called manually from outside. So we consider them "public".

  • hide(): hide the cropper overlay without destroying the instance.
  • show(): un-hide the cropper overlay after it has been hidden with the previous function.
  • toggle(): hide/un-hide the cropper overlay.
  • destroy(): destroy the cropper instance and all the overlayed elements generated.
  • changeImage(url): Update the source image with the passed url.
  • cropSave(parameters): Generates an ajax request calling the url set in the option 'serverScriptSave'. The default script save the thumbnail on the server but you can modify it to do whatever you want. If the argument is an object, the values will be passed as extra parameters to the request.
  • cropDownload(parameters): Calls the url set in the option 'serverScriptDownload'. It is not an ajax request, but a regular location.href on a script that returns a file download header. Or at least that's what the provided script does, then you're free to modify it. If the argument is an object, the values will be passed as extra parameters to the URI.
  • addParameters(parameters): Any parameters added with this function will be submitted with the save or download request. Parameters must be passed as an object {parameter:value}.
  • ratioOn() : Manually turns the selection aspect ratio ON.
  • ratioOff() : Manually turns the selection aspect ratio OFF.

those functions can be used like this :

var myCropper = new uvumiCropper('myImage');
myCropper.hide();
myCropper.show();
myCropper.changeImage('images/my-new-image.jpg');

Implementation

First, you simply import the files provided in the zip archive into your document. While you can insert <script> tags anywhere, we recommend you put them inside the <head> tag:

<head>
<!-- Insert these lines in your document's head -->
<link rel="stylesheet" type="text/css" media="screen" href="css/uvumi-crop.css"/>
<script type="text/javascript" src="js/mootools-for-crop.js"> </script>
<script type="text/javascript" src="js/UvumiCrop.js"> </script>
</head>

Then you must prepare the HTML code. You need one image. Let's just give it the id "myImage".

<div>
<img id="myImage" src="my_image.jpg" alt="My image" />
</div>

"my_image.jpg" is just a random image file name, we just assume it exists.

Then we initialize the cropper object with this image's ID. Don't forget to wrap the ID with quotes when passing it to the object (double or single, doesn't matter);

<script type="text/javascript" >
new uvumiCropper('myImage');
</script>

In the end, if we put everything together. Mootools requires a strict Doctype to work properly. Use something like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html>
<head>
<link rel="stylesheet" type="text/css" media="screen" href="css/uvumi-crop.css"/>
<script type="text/javascript" src="js/mootools-for-crop.js"> </script>
<script type="text/javascript" src="js/UvumiCrop.js"> </script> <script type="text/javascript" >
new uvumiCropper('myImage');
</script>
</head>
<body>
<div>
<img id="myImage" src="my_image.jpg" alt="My image" />
</div>
</body>
</html>

You should get something like this. A cropper with default options: 80*60 pixels, 8 handles, does not preserve aspect ratio, no preview, 50% opacity mask

spacer

Let's try a step above. This time, we'll set a fixed ratio, with a preview, and only four resizing handles. First part where you include the required script is the same. But you'll need an existing container for preview (then we'll see how to overlay it on the images). Where just going to create an empty div, with id "myPreview".

<div>
<div id="myPreview" </div> <img id="myImage" src="my_image.jpg" alt="My image" />
</div>

Then we must tell the script to use this div as a preview container when we initialize the object, with the preview option. We also said we want to keep the selection's aspect ratio, so we're going to set keepRatio to true. Also, just to show how to remove handles, we'll pass an array with only four handles to the handles option, and we'll set the coordinates to true.

<script type="text/javascript" >
new uvumiCropper('myImage',{
keepRatio:true,
preview:'myPreview'
handles:[
['top','left'],
['top','right'],
['bottom','left'],
['bottom','right']
],
coordinates:true
});
</script>

Put it together:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html>
<head>
<link rel="stylesheet" type="text/css" media="screen" href="css/uvumi-crop.css"/>
<script type="text/javascript" src="js/mootools-for-crop.js"> </script>
<script type="text/javascript" src="js/UvumiCrop.js"> </script> <script type="text/javascript" >
new uvumiCropper('myImage',{
keepRatio:true,
preview:'myPreview'
handles:[
['top','left'],
['top','right'],
['bottom','left'],
['bottom','right']
],
coordinates:true
});
</script>
</head>
<body>
<div>
<div id="myPreview" </div> <img id="myImage" src="my_image.jpg" alt="My image" />
</div>
</body>
</html>

And you should get something like this. Try to resize the selection and check out how the preview reacts. Give a try to the manual inputs and see how they maintain proportions and minimums.

spacer

One more example: we're going to modify the genearal look of the cropper by assigning alternate CSS classes. We are also going to change the default minimum width and height, and, just to show that it's possible, disable resizing by removing all the handles. We are also going to try the server side script at the same time by simply adding the downloadButton options. This is not the only way to call the server script, you can do it manually with the provided public functions, but this option automatically generates a button to do it for you.

<script type="text/javascript" >
new uvumiCropper('myImage',{
maskOpicity:0.3,
maskClassName:'blueMask',
resizerClassName:'yellowSelection',
mini:{
x:120,
y:90
},
handles:false,
downloadButton:'Crop!'
});
</script>

HTML will be the same as the first exemple, but we are going to create new CSS classes, corresponding the those we set in the cropper's options

<style type="text/css" >
.yellowSelection{
background:transparent url('blank.gif') center center repeat; //necessary for IE, to give 'consistency' to the slection box
border: 2px dotted #FFB82F;
cursor:pointer;
}

.blueMask{
background-color:#00f;
}
</style>

Resulting code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html>
<head>
<link rel="stylesheet" type="text/css" media="screen" href="css/uvumi-crop.css"/>
<style type="text/css" >
.yellowSelection{
background:transparent url('blank.gif') center center repeat;
border: 2px dotted #FFB82F;
cursor:pointer;
}

.blueMask{
background-color:#00f;
}
</style>
<script type="text/javascript" src="js/mootools-for-crop.js"> </script>
<script type="text/javascript" src="js/UvumiCrop.js"> </script> <script type="text/javascript" >
new uvumiCropper('myImage',{
maskOpacity:0.3,
maskClassName:'blueMask',
resizerClassName:'yellowSelection',
mini:{
x:120,
y:90
},
handles:false,
downloadButton:'Crop!'
});
</script>
</head>
<body>
<div>
<img id="myImage" src="my_image.jpg" alt="My image" />
</div>
</body>
</html>

Should produce this, if not, go back and check for typos or mistakes:

spacer

Ok, last but not least, we'll look at how the callback function works. At the same time, we are going to demonstrate the HTML resizing feature: We will pick an 800px-wide image, but we are going to scale it down to 400px match with the other. So techincally, when we draw a 100px*100px selection on this scaled down image, it virtually represents 200*200px on the full size image, the one the server will use. Same goes with top and height, and preview too, everything has to match this X2 factor. The script handles it and does all the conversion for you if the image has been scaled up or down.

We prepare the HTML first. We are going to create a form with four inputs. For the image, we are going to set the WIDTH attribute (we can either set here or with CSS, works with height too):

<div>
<img id="myImage" width="400" src="my_image.jpg" alt="My image" />
</div>
<form id="myForm" action="crop-image.php" method="post" >
<p>
<input id="input_top" name="top" type="text" readonly="readonly" />
<input id="input_left" name="left" type="text" readonly="readonly" />
<input id="input_width" name="width" type="text" readonly="readonly" />
<input id="input_height" name="height" type="text" readonly="readonly" />
</p>
<p>
<button type="submit" > Send </button>
</p>
</form>

Note that we create four read-only text inputs for this example, but in a real production environment, we'd probably set them as hidden, just like the one containing the image name (or any other kind of unique identifier). Now we want to synchronize those inputs with our cropper:

<script type="text/javascript" >
var myCropper = new uvumiCropper('myImage',{
onComplete:function(top,left,width,height){
$('input_top').set('value', top);
$('input_left').set('value', left);
$('input_width').set('value', width);
$('input_height').set('value', height);
},
preview:true,
coordinatesOpacity:1
});
</script>

While we are at it, why not make the form directly use the built-in cropping functionality? This is just an example--in a real-world case, we would either have the form submit its own value to its own custom script or just have a button to call the cropper's cropSave() function. Here we are just going to have the form submit action call the cropper's function. The inputs are only for visualisation, they are not even going to be submitted.

<script type="text/javascript" >
window.addEvent('domready',function(){
$('myForm').addEvent('submit',function(event){
event.stop(); //we stop the submit event when it happens.
myCropper.cropSave();
});
});
</script>

It's that simple!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"www.w3.org/TR/xhtml1/DTD/
gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.