Crop and upload image on client-side without server-side code involve

Ken picture Ken · Jul 1, 2013 · Viewed 9.4k times · Source

As title said. The requirement is to be able to crop an image before uploading the cropped image to the server. All the work should be done on the client-side. I have heard of the method to crop the image on the server and save it altogether.

But as i use Parse.com service. There is no supported for image manipulation on the server-side so i need to process it locally and upload the finished image directly to Parse.com service.

Example code would be very helpful. Thanks.

Answer

Ken picture Ken · Jul 1, 2013

The solution i used:

First I use a 3rd party javascript library to select the crop area like jCrop. Once i got the coordinates (x1,x2,y1,y2), i draw a copy of an image to a canvas.

          var canvas = document.getElementById('drawcanvas'); 
          var context = canvas.getContext('2d');
          canvas.width = canvas.width; // clear canvas
          var imageObj = new Image();
          imageObj.onload = function() {
            // draw cropped image
            // ...

            context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, sourceWidth, sourceHeight);

            var dataURL = canvas.toDataURL();
          };
          imageObj.src = // image url

After i drew the canvas, i converted the canvas to a DataURL which is in base64 format. Once i've got the DataURL, i use this function i found from the internet where it converts the DataURL to raw binary data.

DataURLConverter: function(data) {
        // convert base64 to raw binary data held in a string
        // doesn't handle URLEncoded DataURIs
        var byteString = atob(data.split(',')[1]);

        // separate out the mime component
        var mimeString = data.split(',')[0].split(':')[1].split(';')[0]

        // write the bytes of the string to an ArrayBuffer
        var ab = new ArrayBuffer(byteString.length);
        var ia = new Uint8Array(ab);
        for (var i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        }
            return ia;
}

When we got the binary data, we then upload this directly to Parse.com. Upload to parse with 'ia' as a data

 var serverUrl = 'https://api.parse.com/1/files/' + fileName;
      $.ajax({
        type: "POST",
        beforeSend: function(request) {
          request.setRequestHeader("X-Parse-Application-Id", "App id");
          request.setRequestHeader("X-Parse-REST-API-Key", "API Key");
          request.setRequestHeader("Content-Type", "File type");
        },
        url: serverUrl,
        data: ia,
        processData: false,
        contentType: false,
        success: function(data) {

        },
        error: function(data) {

        }
      });