How to Crop an Image at Client Side Using Jcrop and Upload It

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

Seahorsepip's answer is fantastic. I made a lot of improvements on the non-fallback answer.

http://jsfiddle.net/w1Lh4w2t/

I would recommend not doing that strange hidden png thing, when an Image object works just as well (so long as we're not supporting fallbacks).

var jcrop_api;
var canvas;
var context;
var image;
var prefsize;

Though even then we are, you're better off getting that data out of the canvas at the end and putting it in that field only at the end.

function loadImage(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
image = new Image();
image.src = e.target.result;
validateImage();
}
reader.readAsDataURL(input.files[0]);
}
}

But, if you want more functions than just crop, if we attach the jcrop to an inserted canvas (which we destroy with the jcrop on refresh). We can easily do anything we can do with a canvas, then validateImage() again and have the updated image visible in place.

function validateImage() {
if (canvas != null) {
image = new Image();
image.src = canvas.toDataURL('image/png');
}
if (jcrop_api != null) {
jcrop_api.destroy();
}
$("#views").empty();
$("#views").append("<canvas id=\"canvas\">");
canvas = $("#canvas")[0];
context = canvas.getContext("2d");
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0);
$("#canvas").Jcrop({
onSelect: selectcanvas,
onRelease: clearcanvas,
boxWidth: crop_max_width,
boxHeight: crop_max_height
}, function() {
jcrop_api = this;
});
clearcanvas();
}

Then on submit we submit any pending operations, like applyCrop() or applyScale(), adding data into hidden fields for fallback stuff, if we have those things needed. We then have a system we can easily just modify the canvas, in any way, then when we submit the canvas data gets sent properly.

function applyCrop() {
canvas.width = prefsize.w;
canvas.height = prefsize.h;
context.drawImage(image, prefsize.x, prefsize.y, prefsize.w, prefsize.h, 0, 0, canvas.width, canvas.height);
validateImage();
}

The canvas is added to a div views.

 <div id="views"></div>

To catch the attached file in PHP (drupal), I used something like:

    function makeFileManaged() {
if (!isset($_FILES['croppedfile']))
return NULL;
$path = $_FILES['croppedfile']['tmp_name'];
if (!file_exists($path))
return NULL;
$result_filename = $_FILES['croppedfile']['name'];
$uri = file_unmanaged_move($path, 'private://' . $result_filename, FILE_EXISTS_RENAME);
if ($uri == FALSE)
return NULL;
$file = File::Create([
'uri' => $uri,
]);
$file->save();
return $file->id();
}

Client-Side Image Manipulation (Cropping)

Basically I would go this way:

  1. Load your image into a <canvas>
  2. Crop the Image: http://www.html5canvastutorials.com/tutorials/html5-canvas-image-crop/
  3. Save a image from the canvas: http://www.html5canvastutorials.com/advanced/html5-canvas-save-drawing-as-an-image/

Here is a very good tutorial.

Disclaimer: I haven't tested this yet, but I heard that this way work.

Also use background-size:cover; or background-size:contain; to get around nasty dimension problems.

Upload and crop image before sending it to the server

jcrop

Jcrop is the quick and easy way to add image cropping functionality to your web application. It combines the ease-of-use of a typical jQuery plugin with a powerful cross-platform DHTML cropping engine that is faithful to familiar desktop graphics applications.

Cropping on server side vs cropping on client and sending base64 string?

I cannot speak about specific implementation performance or file size limits, but I am fairly certain that the desired approach here would be having both client- and server-side cropping, implemented thusly:

  1. If client is able to, crop it client-side
  2. Client sends to server whatever it's got (cropped if able to crop, uncropped otherwise)
  3. Server inspects what it received. If dimensions are greater than accepted, crop it server-side.

This is because even if you decided to implement client-side only, you would be a fool to trust that you'll never receive noncompliant data from your users. Since you're forced by that fact of life to make server-side validation anyway, that is a great opportunity to transparently crop big images, ensuring compliance regardless of the client's capabilities.

I wouldn't worry about client-side performance. 1 or 2 seconds of non-responsiveness when sending the picture wouldn't kill anyone.

About maximum file size, this is also not an issue in this approach, because you ensure the client sends the smaller version it can send. If it cannot crop and the image is too big, it won't be able to send it to you anyway.

Cropping images client side through browser with JavaScript

You can do this by loading the image into a Canvas element and then manipulating the Canvas

Basic tutorial here

http://www.w3schools.com/html/html5_canvas.asp

(plenty more available)



Related Topics



Leave a reply



Submit