14

I am trying to crop image and send the cropped data to server side. I am using imgareaselect plugin. I get the coordinates of selection but could not crop the image. All the solutions available on internet is to preview cropped image using css. But how can I get the cropped data? No need of preview the cropped image. My code is

cropw = $('#cropimg').imgAreaSelect({
             maxWidth: 300, maxHeight: 300,
            aspectRatio: '1:1',
            instance: true,
            handles: true,
            onSelectEnd: function (img, selection) {                
            x1 = selection.x1;
            y1 = selection.y1;
            x2 = selection.x2;
            y2 = selection.y2;
    }
});
Shahbaz Hashmi
  • 2,631
  • 2
  • 26
  • 49
  • I had the same problem once, I used Cropper.js, its easy and well documented. https://github.com/fengyuanchen/cropper. Then go through this to upload it - http://stackoverflow.com/questions/35068954/uploading-an-image-cropped-using-a-cropper-js-plugin – Siddhartha Chowdhury Aug 03 '16 at 18:00
  • their callbacks are looking same. If you are implemented this please provide me code. Here i am getting base64 image string. – Shahbaz Hashmi Aug 03 '16 at 18:06
  • you can use my plugin https://github.com/akshaygoyal88/jquery-img-cropper for this .It will set image in background and than you can set desired height & width – akshay Jul 10 '19 at 07:16

3 Answers3

37

Hey @Shahbaz I was trying out a solution for you using cropper.js.

This is what you can do

Download cropper.js from here

//link the  js files
<head>
  <script src="jquery.js"></script> // optional
  <link  href="cropper.min.css" rel="stylesheet">
  <script src="cropper.min.js"></script>
</head>

Body

<input type="file" name="image" id="image" onchange="readURL(this);"/>
<div class="image_container">
    <img id="blah" src="#" alt="your image" />
</div>
<div id="cropped_result"></div>        // Cropped image to display (only if u want)
<button id="crop_button">Crop</button> // Will trigger crop event

Javascript

<script type="text/javascript" defer>
    function readURL(input) {
        if (input.files && input.files[0]) {
            var reader = new FileReader();
            reader.onload = function (e) {
                $('#blah').attr('src', e.target.result)
            };
            reader.readAsDataURL(input.files[0]);
            setTimeout(initCropper, 1000);
        }
    }
    function initCropper(){
        var image = document.getElementById('blah');
        var cropper = new Cropper(image, {
          aspectRatio: 1 / 1,
          crop: function(e) {
            console.log(e.detail.x);
            console.log(e.detail.y);
          }
        });

        // On crop button clicked
        document.getElementById('crop_button').addEventListener('click', function(){
            var imgurl =  cropper.getCroppedCanvas().toDataURL();
            var img = document.createElement("img");
            img.src = imgurl;
            document.getElementById("cropped_result").appendChild(img);

            /* ---------------- SEND IMAGE TO THE SERVER-------------------------

                cropper.getCroppedCanvas().toBlob(function (blob) {
                      var formData = new FormData();
                      formData.append('croppedImage', blob);
                      // Use `jQuery.ajax` method
                      $.ajax('/path/to/upload', {
                        method: "POST",
                        data: formData,
                        processData: false,
                        contentType: false,
                        success: function () {
                          console.log('Upload success');
                        },
                        error: function () {
                          console.log('Upload error');
                        }
                      });
                });
            ----------------------------------------------------*/
        })
    }
</script>

Hope this helps. Thanks.

Siddhartha Chowdhury
  • 2,724
  • 1
  • 28
  • 46
  • Thanks @Siddhartha it is working. I have upvoted your answer. But still i want to know that how we can crop image using coordinates. Because I have tried many ways for this. – Shahbaz Hashmi Aug 04 '16 at 07:26
  • @siddhartha your demo is very perfect, i was using v3 and yours is 0.8 so i downgraded and it worked perfectly, can you help me with v3? – Akshay Shrivastav Dec 15 '18 at 23:42
  • I wanted to crop for 420*100 how to set it? – Akshay Shrivastav Dec 16 '18 at 00:11
  • what is the use of the "settimeout" ? it seems a bit "magic" to me ? Is it because we need to wait for something to finish , if yes, can't want we hook to the event corresponding to the completion of said "something" ? – allan.simon Dec 19 '18 at 20:13
  • Be careful: The method toBlob will (as of 2019) not work in Microsoft Edge by default. You need a polyfill: https://stackoverflow.com/questions/47475647/canvas-to-blob-on-edge – Max Jan 30 '19 at 13:37
2

Added this one based on the accepted answer, In case anyone is using the jquery wrapper for cropper

let ICropper = (function($) {
  let $cropperCanvasImage = $('#cropper-canvas-image');
  return {
    readUrl,
    cropImage
  }


  function readUrl(input) {
    if (input.files && input.files[0]) {
      let reader = new FileReader();
      reader.onload = function(e) {
        $cropperCanvasImage.attr('src', e.target.result)
      };
      reader.readAsDataURL(input.files[0]);
      setTimeout(initCropper, 1000);
    }
  }

  function initCropper() {
    $cropperCanvasImage.cropper({
      aspectRatio: 1 / 1
    });
  }

  function cropImage() {
    let imgUrl = $cropperCanvasImage.data('cropper').getCroppedCanvas().toDataURL();
    let img = document.createElement("img");
    img.src = imgUrl;
    $("#cropped-result").append(img);
  }
})(jQuery)
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.1/cropper.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script name="jquery-croper-script">
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(require("jquery"),require("cropperjs")):"function"==typeof define&&define.amd?define(["jquery","cropperjs"],r):r(e.jQuery,e.Cropper)}(this,function(c,s){"use strict";if(c=c&&c.hasOwnProperty("default")?c.default:c,s=s&&s.hasOwnProperty("default")?s.default:s,c.fn){var e=c.fn.cropper,d="cropper";c.fn.cropper=function(p){for(var e=arguments.length,a=Array(1<e?e-1:0),r=1;r<e;r++)a[r-1]=arguments[r];var u=void 0;return this.each(function(e,r){var t=c(r),n="destroy"===p,o=t.data(d);if(!o){if(n)return;var f=c.extend({},t.data(),c.isPlainObject(p)&&p);o=new s(r,f),t.data(d,o)}if("string"==typeof p){var i=o[p];c.isFunction(i)&&((u=i.apply(o,a))===o&&(u=void 0),n&&t.removeData(d))}}),void 0!==u?u:this},c.fn.cropper.Constructor=s,c.fn.cropper.setDefaults=s.setDefaults,c.fn.cropper.noConflict=function(){return c.fn.cropper=e,this}}});
</script>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.1/cropper.min.css" />


<input type="file" name="source-image" id="sourceImage" onchange="ICropper.readUrl(this);" />
<div class="image-container">
  <img id="cropper-canvas-image" src="#" alt="your image" />
</div>
<div id="cropped-result"></div>
<button onclick="ICropper.cropImage(this)">Crop</button>
Osvaldo Maria
  • 340
  • 5
  • 14
0

Did you try using a crop plugin for Jquery, like:

https://fengyuanchen.github.io/cropper/

You have to import the scripts in your page:

    <?php
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
    $targ_w = $targ_h = 150;
    $jpeg_quality = 90;

    $src = 'demo_files/pool.jpg';
    $img_r = imagecreatefromjpeg($src);
    $dst_r = ImageCreateTrueColor( $targ_w, $targ_h );

    imagecopyresampled($dst_r,$img_r,0,0,$_POST['x'],$_POST['y'],
    $targ_w,$targ_h,$_POST['w'],$_POST['h']);

    header('Content-type: image/jpeg');
    imagejpeg($dst_r,null,$jpeg_quality);

    exit;
}


?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>

        <script src="http://deepliquid.com/Jcrop/js/jquery.Jcrop.min.js"></script>
        <script src="../js/jquery.Jcrop.js"></script>
        <link rel="stylesheet" href="../css/jquery.Jcrop.css" type="text/css" />
        <link rel="stylesheet" href="demo_files/demos.css" type="text/css" />

        <script language="Javascript">

            $(function(){

                $('#cropbox').Jcrop({
                    aspectRatio: 1,
                    onSelect: updateCoords
                });

            });

            function updateCoords(c)
            {
                $('#x').val(c.x);
                $('#y').val(c.y);
                $('#w').val(c.w);
                $('#h').val(c.h);
            };

            function checkCoords()
            {
                if (parseInt($('#w').val())) return true;
                alert('Selecione a área para recorte.');
                return false;
            };

        </script>

    </head>

    <body>

    <div id="outer">
    <div class="jcExample">
    <div class="article">

        <h1>Crop jQuery</h1>


        <img src="demo_files/pool.jpg" id="cropbox" />


        <form action="crop.php" method="post" onsubmit="return checkCoords();">
            <input type="hidden" id="x" name="x" />
            <input type="hidden" id="y" name="y" />
            <input type="hidden" id="w" name="w" />
            <input type="hidden" id="h" name="h" />
            <input type="submit" value="Crop Image" />
        </form>

    </div>
    </div>
    </div>
    </body>

</html>
  • your updateCoords function is for getting coordinates.I am looking for cropped data. – Shahbaz Hashmi Aug 03 '16 at 18:10
  • To get the coordinates and crop the image using the JCrop... look at the documentation of JCrop, i guess will help you – Sergio Lopes Aug 03 '16 at 18:12
  • and from where I can get the data ? the functions you defined are returning something ??? – Shahbaz Hashmi Aug 03 '16 at 18:15
  • you are right, let's put the complete core. I put the example in PHP, like the documentation, but could be used in any language. I hope it became useful for you. – Sergio Lopes Aug 03 '16 at 18:18
  • Sergio@ My question is for get the cropped data and send to the server. Not server side cropping. Suppose I want to use small image like 300 x 300 just for profile pic. So is this a good approach to send whole image to the server ? – Shahbaz Hashmi Aug 03 '16 at 18:30
  • But you cannot send the image to be cropped and after the return sendo to the server do be stored? – Sergio Lopes Aug 03 '16 at 18:46
  • Try do this: http://tympanus.net/codrops/2014/10/30/resizing-cropping-images-canvas/ – Sergio Lopes Aug 03 '16 at 18:52