Search code examples
jquerycropperjs

How can I constrain the width and height of the croppable area to output the same size image?


Good day -

I'm looking to use the jQuery Cropper.js plugin to create a webform that has field where a user can upload an image and then crop it.

I want the outputted image to always be 580 x 580.

I want to make it so the user can't change the size of the crop area. I want it to always be 580 x 580.

I'm also seeing that when i zoom in/out, which i want, i see the width and height changes.

I've also seen others say I can resize the image on the server, but if when the image is cropped and its really small then I don't see how that is going to work. Scaling the image up would be a problem.

Here is how i have cropper setup.

jQuery( image ).cropper({
  preview: '.img-preview',
  aspectRatio: 1 / 1,
  responsive: true,
  restore: true,
  modal: true,
  guides: false,
  center: true,
  dragMode: 'crop',
  movable: true,
  ready: function (event) { 
    jQuery(this).cropper('setData', { 
      width:  580,
      height: 580
    });
  },
  crop: function(event) {
        jQuery('#height').val(Math.round(event.detail.height));
        jQuery('#width').val(Math.round(event.detail.width));
        jQuery('#x').val(Math.round(event.detail.x));
        jQuery('#y').val(Math.round(event.detail.y));
        jQuery('#angle').val(Math.round(event.detail.rotate)); 
  }
});

I have everything else working. I'm cropping the image, saving the original to the server, cropping the image, converting the cropped image into the a Blob, and then sending that to the server and letting Imagick process the image.

Thanks in advance!


Solution

  • Here are the settings I ended up using for the jquery.cropper:

    jQuery( image ).cropper({
      preview: '.img-preview',
      viewMode:3,
      aspectRatio: 1 / 1,
      strict: true,
      guides: false,
      dragMode: 'move',
      movable: true,
      highlight: true,
      dragCrop: false,
      cropBoxResizable: true,
      data: { width: 580, height: 580 },
      autoCropArea: 0,
      minWidth: 580,
      minHeight: 580,
      maxWidth: 2400,
      maxHeight: 2400,
      ready: function (event) {
    
         jQuery(this).cropper('setData', { 
           width:  580,
          height: 580
         });
    
      },
      crop: function(event) {
            jQuery('#height').val(Math.round(event.detail.height));
            jQuery('#width').val(Math.round(event.detail.width));
            jQuery('#x').val(Math.round(event.detail.x));
            jQuery('#y').val(Math.round(event.detail.y));
            jQuery('#angle').val(Math.round(event.detail.rotate));
            jQuery('#scalex').val(Math.round(event.detail.scaleX)); 
            jQuery('#scaley').val(Math.round(event.detail.scaleY)); 
      }
    });
    

    On the crop button, I had to add this which will size the cropped area to 580x580. I'm using this to show the user a preview of exactly what it will look like.

    $('#btnCrop').click(function() {
    
      var croppedImageDataURL = image.cropper('getCroppedCanvas', {width:580, height:580}).toDataURL("image/jpg");
      result.append( jQuery('<img>').attr('src', croppedImageDataURL) );
    
    });
    

    I have another function for the appendFileandSubmit() action. I added the same thing there to scale the image down to 580x580.

    // click function to handle the image
    function appendFileAndSubmit(){
    
      var form = document.getElementById("cropperform");
    
      var croppedImageDataURL = image.cropper('getCroppedCanvas', {width:580, height:580}).toDataURL("image/jpg");
    
      // Split the base64 string in data and contentType
      var block = croppedImageDataURL.split(";");
      // Get the content type of the image
      var contentType = block[0].split(":")[1];// In this case "image/gif"
      // get the real base64 content of the file
      var realData = block[1].split(",")[1];// In this case "R0lGODlhPQBEAPeoAJosM...."
    
      // Convert it to a blob to upload
      var blob = b64toBlob(realData, contentType);
    
      // Create a FormData and append the file with "image" as parameter name
      var formDataToUpload = new FormData(form);
      formDataToUpload.append("image", blob);
    
    
    
      /**
     * The following code should send 2 post parameters:
     * filename: providen by the text input
     * image: a file, dinamically added from a base64 string using javascript
     *
     * Is up to you how to receive the file in the Server side.
     */
      jQuery.ajax({
          url:"finish-image.php",
          data: formDataToUpload,// Add as Data the Previously create formData
          type:"POST",
          contentType:false,
          processData:false,
          cache:false,
          dataType:"json", // Change this according to your response from the server.
          error:function(err){
              console.error(err);
          },
          success:function(data){
              console.log(data);
    
              jQuery('#FinalStep .outputMsg').html('<p>Success!</p>');
          },
          complete:function(){
              console.log("Request finished.");
          }
      });
    
    }
    

    This will submit the image at 580x580 to a script for processing.