Cropping Images In HTML Using jQuery

Here, we are cropping an image in jQuery using Cropper and later, we are providing a functionality to download at client machine or save the cropped image on SharePoint Server.

Here, we are creating the functionality of Image Cropping which will crop the image and later on, you can save those images at a client machine or you can save the cropped images on the SharePoint Server.
 
I have created an Image Cropping project and attached the complete project with this blog. You can directly start the download and can customize it based on your requirement. 
 
As I have implemented the Image Cropping functionality at SharePoint Server, it will be saved in the picture library in SharePoint which I have named as 'Image'. 
 
Image Crop in JQuery HTML
 
In the Image, we can see that we have the feature of image cropping along with multiple other features like aspect ratio, toggle etc. which we can use to customize based on our requirement.
 
The cropped image can be previewed as -
 
Image Crop in JQuery HTML 
 
In the preview cropped image, we have options to Download/Save and close. 
 
Sample script to preview image of 320*180.
  1. <button type="button" class="btn btn-success" data-method="getCroppedCanvas" data-option="{ "width": 320, "height": 180 }">  
  2.     <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="$().cropper("getCroppedCanvas", { width: 320, height: 180 })"> 320×180 </span>  
  3. </button> 
We can also pass the parameter for different image inputs based on our requirement.
  1. //To save Image in our SharePoint Library can be achieved with the below code.  
  2. < script >  
  3.     /* Cropped Image Code Section */  
  4.     function SaveCroppedImg() {  
  5.         var fileName = 'CroppedImg'//you can modify based on input from file upload control  
  6.         var fileType = '';  
  7.         var hrefVal = $("#download").attr("href");  
  8.         console.log(hrefVal);  
  9.         var ImageURL = hrefVal; //this Image is now in Img64 type.  
  10.         // Split the base64 string in data and contentType  
  11.         var block = ImageURL.split(";");  
  12.         // Get the content type of the image  
  13.         var contentType = block[0].split(":")[1];  
  14.         if ((contentType == 'image/gif') || (contentType == 'image/GIF')) {  
  15.             fileType = '.gif';  
  16.         } else if ((contentType == 'image/png') || (contentType == 'image/PNG')) {  
  17.             fileType = '.png';  
  18.         } else if ((contentType == 'image/jpg') || (contentType == 'image/JPG')) {  
  19.             fileType = '.jpg';  
  20.         } else if ((contentType == 'image/jpeg') || (contentType == 'image/JPEG')) {  
  21.             fileType = '.jpg';  
  22.         }  
  23.         // get the real base64 content of the file  
  24.         var realData = block[1].split(",")[1];  
  25.         // Convert it to a blob to upload  
  26.         var blob = b64toBlob(realData, contentType);  
  27.         uploadCroppedImage(blob, fileName + fileType);  
  28.     }  
  29.   
  30. function b64toBlob(b64Data, contentType, sliceSize) {  
  31.     contentType = contentType || '';  
  32.     sliceSize = sliceSize || 512;  
  33.     var byteCharacters = atob(b64Data);  
  34.     var byteArrays = [];  
  35.     for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {  
  36.         var slice = byteCharacters.slice(offset, offset + sliceSize);  
  37.         var byteNumbers = new Array(slice.length);  
  38.         for (var i = 0; i < slice.length; i++) {  
  39.             byteNumbers[i] = slice.charCodeAt(i);  
  40.         }  
  41.         var byteArray = new Uint8Array(byteNumbers);  
  42.         byteArrays.push(byteArray);  
  43.     }  
  44.     var blob = new Blob(byteArrays, {  
  45.         type: contentType  
  46.     });  
  47.     return blob;  
  48. }  
  49.   
  50. function uploadCroppedImage(buffer, fileName) {  
  51.     var call = uploadCroppedDocument(buffer, fileName);  
  52.     call.done(function(firstData, textStatus, jqXHR) {  
  53.         //get the URL of the Uploaded Image  
  54.         var call2 = getItem(firstData.d);  
  55.         call2.done(function(SecondData, textStatus, jqXHR) {  
  56.             //Update the metadata of the uploaded Image.  
  57.             var call3 = updateMetadata(fileServerUrl);  
  58.             call3.done(function(data, textStatus, jqXHR) {  
  59.                 console.log("Image Metadata Updated");  
  60.             });  
  61.             call3.fail(function(jqXHR, textStatus, errorThrown) {  
  62.                 failHandler(jqXHR, textStatus, errorThrown);  
  63.             });  
  64.         });  
  65.         call2.fail(function(jqXHR, textStatus, errorThrown) {  
  66.             failHandler(jqXHR, textStatus, errorThrown);  
  67.         });  
  68.     });  
  69.     call.fail(function(jqXHR, textStatus, errorThrown) {  
  70.         failHandler(jqXHR, textStatus, errorThrown);  
  71.     });  
  72. }  
  73.   
  74. function uploadCroppedDocument(buffer, fileName) {  
  75.     var url = String.format("{0}/_api/Web/Lists/getByTitle('Images')/RootFolder/Files/Add(url='{1}', overwrite=true)", _spPageContextInfo.webAbsoluteUrl, fileName);  
  76.     var call = jQuery.ajax({  
  77.         url: url,  
  78.         type: "POST",  
  79.         data: buffer,  
  80.         processData: false,  
  81.         headers: {  
  82.             Accept: "application/json;odata=verbose",  
  83.             "X-RequestDigest": jQuery("#__REQUESTDIGEST").val(),  
  84.             "Content-Length": buffer.byteLength  
  85.         }  
  86.     });  
  87.     return call;  
  88. }  
  89.   
  90. function getItem(file) {  
  91.     fileServerUrl = "";  
  92.     fileServerUrl = file.ServerRelativeUrl;  
  93.     var url = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbytitle('Images')/GetItems";  
  94.     var call = jQuery.ajax({  
  95.         url: file.ListItemAllFields.__deferred.uri,  
  96.         type: "GET",  
  97.         dataType: "json",  
  98.         headers: {  
  99.             Accept: "application/json;odata=verbose"  
  100.         },  
  101.         success: function(data) {  
  102.             console.log(data.d.result);  
  103.         },  
  104.         error: function(data) {  
  105.             alert('Error');  
  106.         }  
  107.     });  
  108.     return call;  
  109. }  
  110.   
  111. function updateMetadata(fileUrl) {  
  112.     var restSource = _spPageContextInfo.webAbsoluteUrl + "/_api/Web/lists/getbytitle('Images')/rootfolder/files/getbyurl(url='" + fileUrl + "')/listitemallfields";  
  113.     var dfd = $.Deferred();  
  114.     var titleVal = 'Crooped Image Title'//$("#txtTitle").val();  
  115.     $.ajax({  
  116.         'url': restSource,  
  117.         'method''POST',  
  118.         'data': JSON.stringify({  
  119.             '__metadata': {  
  120.                 'type''SP.ListItem'  
  121.             },  
  122.             'Title': titleVal  
  123.         }),  
  124.         'headers': {  
  125.             'accept''application/json;odata=verbose',  
  126.             'content-type''application/json;odata=verbose',  
  127.             'X-RequestDigest': $('#__REQUESTDIGEST').val(),  
  128.             'X-Http-Method''PATCH',  
  129.             "If-Match""*"  
  130.         },  
  131.         'success'function(data) {  
  132.             var d = data;  
  133.             dfd.resolve();  
  134.         },  
  135.         'error'function(err) {  
  136.             dfd.reject();  
  137.         }  
  138.     });  
  139.     return dfd;  
  140. }  
  141.   
  142. function failHandler(jqXHR, textStatus, errorThrown) {  
  143.     var response = JSON.parse(jqXHR.responseText);  
  144.     var message = response ? response.error.message.value : textStatus;  
  145.     alert("Call failed. Error: " + message);  
  146. }  
  147. /* End Cropped Image Section*/  
  148. < /script> 
Let me know if you face issues with any implementation.