How should I crop an image at client side using jcrop and upload it?

Here’s basic html 5 code:

https://jsfiddle.net/zm7e0jev/

This code crops the image, shows a preview and sets the value of an input element to the base64 encoded cropped image.

You can fetch the image file in php the following way:

//File destination
$destination = "/folder/cropped_image.png";
//Get convertable base64 image string
$image_base64 = $_POST["png"];
$image_base64 = str_replace("data:image/png;base64,", "", $image_base64);
$image_base64 = str_replace(" ", "+", $image_base64);
//Convert base64 string to image data
$image = base64_decode($image_base64);
//Save image to final destination
file_put_contents($destination, $image);

Submitting base64 image string as a post variable has it’s server post size limits and base64 encoding makes the cropped image file size even bigger (~33%) then the raw data of the cropped image would be which makes the upload take even longer.

To set the post size limit: What is the size limit of a post request?

Keep in mind that an increased post size limit can be abused for a DoS attack as example.

Instead I suggest converting the base64 cropped image to a data blob and then add it to the form on submit as a file:

https://jsfiddle.net/g3ysk6sf/

Then you can fetch the image file in php the following way:

//File destination
$destination = "/folder/cropped_image.png";
//Get uploaded image file it's temporary name
$image_tmp_name = $_FILES["cropped_image"]["tmp_name"][0];
//Move temporary file to final destination
move_uploaded_file($image_tmp_name, $destination);

Update:

FormData() is only partially support in IE10 and not supported in older versions of IE

So I suggest sending the base64 string as a fallback, though this will cause problems with bigger images so it needs to check the filesize and show an error popup when the image is above a specific size.

I’ll post an update with the fallback code below when I’ve got it working.

Update 2:

I added a fallback for IE10 and below:

https://jsfiddle.net/oupxo3pu/

The only limitation is the image size that can be submitted when using IE10 and below, in case the image size is too big the js code will throw an error. The maximum size to work for post values is different between each server, the js code has a variable to set the maximum size.

The php code below is adapted to work with above fallback:

//File destination
$destination = "/folder/cropped_image.png";
if($_POST["png"]) {//IE10 and below
    //Get convertable base64 image string
    $image_base64 = $_POST["png"];
    $image_base64 = str_replace("data:image/png;base64,", "", $image_base64);
    $image_base64 = str_replace(" ", "+", $image_base64);
    //Convert base64 string to image data
    $image = base64_decode($image_base64);
    //Save image to final destination
    file_put_contents($destination, $image);
} else if($_FILES["cropped_image"]) {//IE11+ and modern browsers
    //Get uploaded image file it's temporary name
    $image_tmp_name = $_FILES["cropped_image"]["tmp_name"][0];
    //Move temporary file to final destination
    move_uploaded_file($image_tmp_name, $destination);
}

There is no fallback code for the canvas element yet, I’m looking into it.

The post size limitation in the fallback for older browsers is one of the reasons I dropped support for older browsers myself.

Update 3:

The fallback I recommend for the canvas element in IE8:

http://flashcanvas.net/

It supports all the canvas functions the cropping code needs.

Keep in mind it requires flash. There is a canvas fallback (explorercanvas) that does not require flash but it does not support the function toDataURL() which we need to save our cropped image.

Leave a Comment