2

I already implemented drag&drop image sorting with Fineuploader (using jQuery Sortable for this), and now I would like to add jqCrop support (http://adriengibrat.github.io/jQuery-crop/). Ideally I would like to let the user crop the image before upload.

What would be the best way to implent this?

Ray Nicholus
  • 19,538
  • 14
  • 59
  • 82
user1049961
  • 2,656
  • 9
  • 37
  • 69

2 Answers2

3

First off, I so no reason to use jqCrop. It doesn't appear to do anything that JCrop doesn't already do, and jCrop is much more widely used (and probably tested as a result).

With that in mind, here are the steps you must follow:

Step 1: Use JCrop to gather dimensions for the new image and then draw the desired section of the image onto a <canvas>.

You'll need to so the latter part of this yourself since JCrop doesn't actually seem to modify the image. However, there's a snippet of code that shows how this can be done. The steps that the code follow are:

  1. Grab dimensions of the crop from JCrop
  2. Draw the image onto a <canvas>, ignoring everything outside of the cropped dimensions.
  3. Grab a base64 representation of the <canvas> via a data URI. You'll need this data URI for the next step.

Step 2: Turn the cropped version of the image into a Blob

Fine Uploader already does this for it's image scaling feature internally. It seems reasonable to expose this via an API method in a future release (maybe even as part of the current or next release cycle), but, for now, you can just make use of Fine Uploader's internal "private" function that does this on the prototype of the scaling module.

Note - This code accesses a private function. It may change, be renamed, or be removed at any time. Please keep this in mind when you use this. I will be sure to update this answer once we make this all easier via an API method so direct access to this private method isn't necessary anymore:

var croppedImageAsBlob = qq.Scaler.prototype._dataUriToBlob(data_uri_from_step1_above);

Step 3: Submit the cropped Blob to Fine Uploader

The call in step 2 will return a Blob. You can then pass this Blob to Fine Uploader via the addBlobs API method like this:

uploader.addBlobs({blob: croppedImageAsBlob, name: "my cropped image.png"});

Ray Nicholus
  • 19,538
  • 14
  • 59
  • 82
  • Thanks, what I still don't get is how to _replace_ the image in the queue with the cropped version. Ie., on file select, it get's loaded into canvas, cropped, and than the original file in the queue has to be replaced, right? – user1049961 May 04 '14 at 07:18
  • You can either issue a cancel API call for the original, or simply don't add the original to Fine Uploader. – Ray Nicholus May 04 '14 at 13:21
  • @user1049961 Note that Fine Uploader will be adding a way to easily pass a canvas into the uploader via the API in the upcoming 5.1 release. This means that you will not need step 2 or 3. https://github.com/Widen/fine-uploader/issues/1198 – Ray Nicholus Oct 03 '14 at 04:18
  • @ Ray Nicholus with changing the name is possible – RahulG Mar 14 '15 at 02:49
1

Clipping

It seems that jqCrop doesn't really crop anything. If you want to let users crop their images before uploading, you have to edit images with javascript which can be done with Canvas.clip()

This library works pretty well: http://blueimp.github.io/JavaScript-Load-Image/

Uploading

After image editing, you can get Base64 encoded image data from canvas then upload it to server:

Javascript:

canvas.toDataURL();

PHP:

$encodedData = str_replace(' ','+',$encodedData);
$decocedData = base64_decode($encodedData);
Peter Chung
  • 457
  • 6
  • 14
  • Thanks for great answer. When using the first method, how can I pass the cropped image into Fineuploader? – user1049961 May 03 '14 at 10:08
  • Fineuploader doesn't provide an option to upload through canvas. You may consider switch to https://github.com/blueimp/jQuery-File-Upload – Peter Chung May 03 '14 at 10:14
  • I really tried hard to use blueimps FileUpload, but it was impossible to integrate with existing forms. I love FineUploader in this regard, and generally like FineUploader way more. But, this might be the case where it fails short... – user1049961 May 03 '14 at 10:17
  • 2
    It is trivial to pass an image represented on a canvas to fine Uploader. Just convert the canvas to a blob and pass the blob to Fine Uploader's addBlobs API method. – Ray Nicholus May 03 '14 at 10:24
  • I just found a method to use: http://docs.fineuploader.com/api/methods.html#addBlobs https://github.com/blueimp/JavaScript-Canvas-to-Blob – Peter Chung May 03 '14 at 10:24
  • Yes, you can do this, but it's not required. Fine Uploader converts canvas to blob internally for its scaling feature, and it does not use blueimp's library to do this. We could easily expose that logic to make it even easier for users I suppose. – Ray Nicholus May 03 '14 at 10:33
  • Thanks Ray. Can you give me some hints how to do this. I have autoUpload already set to false. So, I guess the user selects file, it should load into canvas, get cropped, and be passed back to Fineuploader to upload... – user1049961 May 03 '14 at 10:35
  • 2
    I only have access to my phone right now and it is tough to type anything long. I'll provide an alternate answer sometime today that covers all this. Stay tuned... – Ray Nicholus May 03 '14 at 10:38
  • I've created an answer that should address your concerns. – Ray Nicholus May 03 '14 at 14:53