Image Crop and Upload with jQuery and PHP

There are many good jQuery plugins are available  today to crop image on the fly. jCropimgAreaSelect and many more. Today I am going to show you how you can implement imgAreaSelect jQuery plugin for cropping image on your project with instant upload preview.

imgAreaSelect is one of the most powerful jQuery plugin for working with images that can work in all major old and new browser. It is easy to configure and implement.

Live Demo Download Source

HTML Image Uploading Form

As usual we will start with html markup. We need to create a simple file upload form with 4 hidden fields with blank value. These hidden fields will need to submit image selection values. We also need to add a img without src attribute. Image will be appear here for instant preview

<!-- image preview area-->
<img id="uploadPreview" style="display:none;"/>
  
<!-- image uploading form -->
<form action="upload.php" method="post" enctype="multipart/form-data">
  <input id="uploadImage" type="file" accept="image/jpeg" name="image" />
  <input type="submit" value="Upload">

  <!-- hidden inputs -->
  <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" />
</form>

jQuery and JavaScript Part

The following jQuery and JavaScript code holds some imgAreaSelect configurations. We also need to use FileReader html5 file reader api to make instant image preview.

// set info for cropping image using hidden fields
function setInfo(i, e) {
  $('#x').val(e.x1);
  $('#y').val(e.y1);
  $('#w').val(e.width);
  $('#h').val(e.height);
}

$(document).ready(function() {
  var p = $("#uploadPreview");

  // prepare instant preview
  $("#uploadImage").change(function(){
    // fadeOut or hide preview
    p.fadeOut();

    // prepare HTML5 FileReader
    var oFReader = new FileReader();
    oFReader.readAsDataURL(document.getElementById("uploadImage").files[0]);

    oFReader.onload = function (oFREvent) {
         p.attr('src', oFREvent.target.result).fadeIn();
    };
  });

  // implement imgAreaSelect plug in (http://odyniec.net/projects/imgareaselect/)
  $('img#uploadPreview').imgAreaSelect({
    // set crop ratio (optional)
    aspectRatio: '1:1',
    onSelectEnd: setInfo
  });
});

PHP Part

The following php code holds some basic download validation and php gd based image resize functionalities

$valid_exts = array('jpeg', 'jpg', 'png', 'gif');
$max_file_size = 200 * 1024; #200kb
$nw = $nh = 200; # image with & height

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  if ( isset($_FILES['image']) ) {
    if (! $_FILES['image']['error'] && $_FILES['image']['size'] < $max_file_size) {
      # get file extension
      $ext = strtolower(pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION));
      # file type validity
      if (in_array($ext, $valid_exts)) {
          $path = 'uploads/' . uniqid()  . '.' . $ext;
          $size = getimagesize($_FILES['image']['tmp_name']);
          # grab data form post request
          $x = (int) $_POST['x'];
          $y = (int) $_POST['y'];
          $w = (int) $_POST['w'] ? $_POST['w'] : $size[0];
          $h = (int) $_POST['h'] ? $_POST['h'] : $size[1];
          # read image binary data
          $data = file_get_contents($_FILES['image']['tmp_name']);
          # create v image form binary data
          $vImg = imagecreatefromstring($data);
          $dstImg = imagecreatetruecolor($nw, $nh);
          # copy image
          imagecopyresampled($dstImg, $vImg, 0, 0, $x, $y, $nw, $nh, $w, $h);
          # save image
          imagejpeg($dstImg, $path);
          # clean memory
          imagedestroy($dstImg);
          echo "<img src='$path' />";
          
        } else {
          echo 'unknown problem!';
        } 
    } else {
      echo 'file is too small or large';
    }
  } else {
    echo 'file not set';
  }
} else {
  echo 'bad request!';
}

51 comments:

  1. DOes not work in IE

    ReplyDelete
    Replies
    1. You are right! Older version of IE does not support html5 FileReader api. That's why it is not working on your IE browser. It will work on IE10 or later browsers. If you want to give IE9 support you need to rewrite the code. First you need to upload image file to server and then you need to allow cropping.

      Delete
    2. Can you provide source code for that?

      Delete
    3. I hope it can help you http://keithics.com/blog/jquery/ajaxcrop-jquery-and-php-crop-tool
      Thanks!

      Delete
    4. cropping is not work proper. when i upload large image and display with some height and width then i apply croping my cropping image is not same with selection area.

      Delete
  2. Your script is not calculating aspect ratio on right way

    ReplyDelete
  3. When i load a big image (ex: 1500px x 900px) the browser rezise the image automatically, putting a magnifier in the cursor.
    And when i select a area, crop and upload this not crop my selected area but the real size area.

    Some idea to solve this?

    ReplyDelete
    Replies
    1. II had a similar problem, the following worked for me ( I'm relatively new to jquery and javascript so i'm sure there is a better and cleaner way but it works for me) change your setInfo function to this:

      function setInfo(i, e) {
      if ( originalImgWidth>= scaledImgWidth){ var ar = originalImgWidth/scaledImgWidth;}
      else { var ar = 1;}
      $('#x').val(e.x1*ar);
      $('#y').val(e.y1*ar);
      $('#w').val(e.width*ar);
      $('#h').val(e.height*ar);
      }

      I don't know what way is used to scale your image but i'm sure you can find the original and scaled width of your image on your own.

      Delete
  4. can you please tell me how to write the upload.php using java

    ReplyDelete
    Replies
    1. Sorry! I am not familiar with Java. but i think http://docs.oracle.com/javase/6/docs/api/java/awt/image/CropImageFilter.html package can help you.
      Thanks!

      Delete
  5. What if I want to save BOTH the original AND the cropped image?

    ReplyDelete
    Replies
    1. Just move uploaded file
      move_uploaded_file($_FILES['image']['tmp_name'], 'path/to/dir/file.jpg')

      Delete
    2. Oh man, thanks a lot! Cheers!

      Delete
    3. Where in the code would you put the move_uploaded_file() in upload.php?

      Delete
    4. inside
      if(in_array($ext, $valid_exts))
      {
      .....
      }

      Delete
  6. Hi, there is method for set a max width for image preview?

    ReplyDelete
  7. cropping is not work proper. when i upload large image and display with some height and width then i apply croping my cropping image is not same with selection area.

    ReplyDelete
  8. how can i get dimensions of selected area??

    ReplyDelete
  9. TypeError: $(...).imgAreaSelect is not a function


    onSelectEnd: function setInfo(i, e) {

    what is this error i dont understand i have included js/jquery.imgareaselect.pack.js
    and supported jquery files and again it is showing this type of error i dont know the reason can u please resolve this issue

    ReplyDelete
  10. Great script! Is there anyway I can preset the cropping size square so it is only one size and cant be resized by the user?

    ReplyDelete
  11. How can I define the max side file of the output, I mean, I do no want to keep a particular aspect ratio, I want it always to be something with 700x200 for example

    ReplyDelete
  12. This is your new script file, for all those who were having ratio probems when the image is bigger than how it was scaled to fit the screen.

    // set info for cropping image using hidden fields
    function setInfo(i, e) {
    // Get on screen image
    var screenImage = $("#uploadPreview");

    // Create new offscreen image to test
    var theImage = new Image();
    theImage.src = screenImage.attr("src");

    // Get accurate measurements from that.
    var imageWidth = theImage.width;

    //Get width of resized image
    var scaledimagewidth = document.getElementById("uploadPreview").width;

    if ( imageWidth > scaledimagewidth){ var ar = imageWidth/scaledimagewidth;}
    else { var ar = 1;}
    $('#x').val(e.x1*ar);
    $('#y').val(e.y1*ar);
    $('#w').val(e.width*ar);
    $('#h').val(e.height*ar);
    }

    $(document).ready(function() {
    var p = $("#uploadPreview");

    // prepare instant preview
    $("#uploadImage").change(function(){
    // fadeOut or hide preview
    p.fadeOut();

    // prepare HTML5 FileReader
    var oFReader = new FileReader();
    oFReader.readAsDataURL(document.getElementById("uploadImage").files[0]);

    oFReader.onload = function (oFREvent) {
    p.attr('src', oFREvent.target.result).fadeIn();
    };
    });

    // implement imgAreaSelect plug in (http://odyniec.net/projects/imgareaselect/)
    $('img#uploadPreview').imgAreaSelect({
    // set crop ratio (optional)
    aspectRatio: '2:1',
    onSelectEnd: setInfo
    });
    });

    ReplyDelete
  13. this is good script but i want to not refresh my page ..
    is there a solution in ajax,jquery and php ...?
    i have a form with multiple things like product name , image , price and when i used ur script it post the value that dismiss my recent values like product name etc ....
    guys give me proper solution thanx

    ReplyDelete
    Replies
    1. i find my previous problem solution ,... now i am doing this with Modal
      i have one more query .... how can i show my cropping part in another Div before uploading to server...

      Delete
  14. i have one more query .... how can i show my cropping part in another Div before uploading to server...

    ReplyDelete
  15. very buggy... does not save the crop... waiste of time

    ReplyDelete
  16. This may be relevant to the article. Image crop/resize/rotate on the front-end and upload jquery plugin: https://github.com/andyvr/picEdit

    ReplyDelete
  17. Very useful, see this tutorial also, it may help you: http://www.bewebdeveloper.com/tutorial-about-crop-photo-using-php-and-jquery

    ReplyDelete
  18. Hello,once i click on browe image was not display whats wrong can you please tel me......

    ReplyDelete
  19. Thank you very much for your work.
    Helps a lot

    ReplyDelete
  20. Nice Post...
    Thank you very much for shared it. Very usefull....

    ReplyDelete
  21. How to get cropped image from imgAreaSelect after click and when cropping the image the saved cropped image should not affect?

    ReplyDelete
    Replies
    1. after cropping I have to show the cropped image in a td on a button click event. After that when I crop the image again the saved image shouldnt change.

      Delete
  22. hii it is not working in lightbox.. plz help

    ReplyDelete
  23. very nice website
    thanks
    man.
    http://www.onlineperiod.cf/

    ReplyDelete
  24. Great Information sir.
    thanks
    Read about technology here
    hire php developers india

    ReplyDelete
  25. Hi,

    Thank you for your solution, Great work.

    How can I change the cropping ratio?

    Thank you

    ReplyDelete
  26. Hello,

    i am having a problem with the selection area, when i put a photo, the default selection mantains with it, but when i change the photo to another with bigger proportions, whe selected area has the same size and the grey area has the size of the previous photo, how can i change the grey area dynamically to fit any photo i put there? i am doing this inside a modal,

    Thanks,

    Fabio Ferreira

    ReplyDelete
  27. Hi,

    How can we show a default crop area in the image before we start clicking on the image?

    ReplyDelete
  28. hey,
    image after choosing image not working on bootstrap modal

    ReplyDelete
  29. Lớp học kế toán tổng hợp thực hành tại hải phòng
    Lớp học kế toán tổng hợp thực hành tại biên hòa đồng nai
    Lớp học kế toán tổng hợp thực hành tại vinh nghệ an
    Lớp học kế toán tổng hợp thực hành tại hải dương
    Lớp học kế toán tổng hợp thực hành tại ninh bình
    Lớp học kế toán tổng hợp thực hành tại hưng yên
    Lớp học kế toán tổng hợp thực hành tại phú thọ
    Lớp học kế toán tổng hợp thực hành tại hà nam
    Lớp học kế toán tổng hợp thực hành tại vĩnh phúc
    Lớp học kế toán tổng hợp thực hành tại bắc giang
    Lớp học kế toán tổng hợp thực hành tại thái nguyên
    Lớp học kế toán tổng hợp thực hành tại thái bình
    Lớp học kế toán tổng hợp thực hành tại nam định
    Lớp học kế toán tổng hợp thực hành tại thanh hóa
    Lớp học kế toán tổng hợp thực hành tại tphcm
    Lớp học kế toán tổng hợp thực hành tại bắc ninh
    Lớp học kế toán tổng hợp thực hành tại hà đông
    Lớp học kế toán tổng hợp thực hành tại long biên
    Lớp học kế toán tổng hợp thực hành tại thanh xuân
    Lớp học kế toán tổng hợp thực hành tại cầu giấy
    khóa học kế toán toán dành cho giám đốc và nhà quản lý
    công cụ dụng cụ
    thủ tục thanh lý tài sản cố định
    bảng cân đối kế toán
    thuế thu nhập cá nhân năm 2015
    phần mềm htkk 3.3.1

    ReplyDelete
  30. I change this part:
    $nw = $nh = 400; # image with # height

    $nw = 450;
    $nh = 685;

    but it doesn't change the crop box area. It is still in square (1:1)

    Any idea?

    ReplyDelete
  31. When I upload a large photo (768:512) the charpness of the image is very bad. Is there a solution for this?
    Kind regards

    ReplyDelete

Go to top