Crop An Image And Upload Using Jquery, HTML5 and PHP

Crop An Image And Upload Using Jquery, HTML5 and PHP

In this post I’ve designed a tutorial about “How to crop an image by using jquery, HTML5 and PHP”. After reading this article, you will be able to implement an image cropping functionality in your web application very quick and easily. Basically the script is developed for a User Management System such as  social networking website to give the flexibility of cropping an image when the user uploads his profile picture. Image cropping reduces  uploaded image size and saves your web space on the server.

Crop An Image And Upload Using Jquery, HTML5 and PHP

Crop An Image And Upload Using Jquery, HTML5 and PHP

What I’ve used in this tutorial?

1. HTML5 FileReader class object : Today all the modern browsers support HTML5 and it comes with many amazing features. HTML5 FileReader is a javascript class that is used to read the file, selected through a file input for temporary purpose. You can get the full information about the selected file and see a preview before uploading it to the server. You just have to create an object of this class and fetch all properties by it’s event handlers.

2. jCrop Jquery Plugin: jCrop Jquery Plugin is developed to select the crop region on a given particular image. The plugin can be easily attached to any image.

3. Resize and upload with PHP : PHP file has been written to upload the cropped image to your web server. It has used basic image resampling, resizing and uploading functions.

You can view the demo to understand the full functionality of this script. You just have to ensure that your browser (should be latest version) supports HTML5.

Basic Files used in the project are:

1. index.php – main home page

2. jquery.Jcrop.min.js – Jcrop plugin

3. jquery.min.js – Jquery file

4. script.js – for basic validations and cropping the image

5. upload.php -  to upload the cropped image

and some css files to decorate the project

Script.js

//Make global variables for selected image for further usage
var selectImgWidth,selectImgHeight,jcrop_api, boundx, boundy,isError=false;
$(document).ready(function(){
	$("#image_file").change(function(){
		var previewId = document.getElementById('load_img');
	    var thumbId = document.getElementById('thumb');
	    previewId.src = '';
		$('#image_div').hide();
	    var flag = 0;

	    // Get selected file parameters
	    var selectedImg = $('#image_file')[0].files[0];

	    //Check the select file is JPG,PNG or GIF image
	    var regex = /^(image/jpeg|image/png)$/i;
	    if (! regex.test(selectedImg.type)) {
	        $('.error').html('Please select a valid image file (jpg and png are allowed)').fadeIn(500);
	        flag++;
	        isError = true;
	    }

	    // Check the size of selected image if it is greater than 250 kb or not
	    else if (selectedImg.size > 250 * 1024) {
	        $('.error').html('The file you selected is too big. Max file size limit is 250 KB').fadeIn(500);
	        flag++;
	        isError = true;
	    }

	    if(flag==0){
	    isError=false;
	    $('.error').hide(); //if file is correct then hide the error message

	    // Preview the selected image with object of HTML5 FileReader class
	    // Make the HTML5 FileReader Object
	    var oReader = new FileReader();
	        oReader.onload = function(e) {

	        // e.target.result is the DataURL (temporary source of the image)
	        	thumbId.src = previewId.src=e.target.result;

	        	// FileReader onload event handler
	        	previewId.onload = function () {

	            // display the image with fading effect
	            $('#image_div').fadeIn(500);
	            selectImgWidth = previewId.naturalWidth; //set the global image width
	        	selectImgHeight = previewId.naturalHeight;//set the global image height

	            // Create variables (in this scope) to hold the Jcrop API and image size

	            // destroy Jcrop if it is already existed
	            if (typeof jcrop_api != 'undefined')
	                jcrop_api.destroy();

	            // initialize Jcrop Plugin on the selected image
	            $('#load_img').Jcrop({
	                minSize: [32, 32], // min crop size
	               // aspectRatio : 1, // keep aspect ratio 1:1
	                bgFade: true, // use fade effect
	                bgOpacity: .3, // fade opacity
	                onChange: showThumbnail,
	                onSelect: showThumbnail
	            }, function(){

	                // use the Jcrop API to get the real image size
	                var bounds = this.getBounds();
	                boundx = bounds[0];
	                boundy = bounds[1];

	                // Store the Jcrop API in the jcrop_api variable
	                jcrop_api = this;
	            });
	        };
	    };

	    // read selected file as DataURL
	    oReader.readAsDataURL(selectedImg);
	}
	})
})

function showThumbnail(e)
{
	var rx = 155 / e.w; //155 is the width of outer div of your profile pic
	var ry = 190 / e.h; //190 is the height of outer div of your profile pic
	$('#w').val(e.w);
    $('#h').val(e.h);
    $('#w1').val(e.w);
    $('#h1').val(e.h);
    $('#x1').val(e.x);
    $('#y1').val(e.y);
    $('#x2').val(e.x2);
    $('#y2').val(e.y2);
	$('#thumb').css({
		width: Math.round(rx * selectImgWidth) + 'px',
		height: Math.round(ry * selectImgHeight) + 'px',
		marginLeft: '-' + Math.round(rx * e.x) + 'px',
		marginTop: '-' + Math.round(ry * e.y) + 'px'
	});
}

function validateForm(){
	if ($('#image_file').val()=='') {
        $('.error').html('Please select an image').fadeIn(500);
        return false;
    }else if(isError){
    	return false;
    }else {
    	return true;
    }
}

upload.php

<!--?php <br ?-->/*
* @author Manish Jangir
* @website blogaddition.com
* @script upload cropped image
*/

function get_virtual_img($mime,$temp_file){
$vir_img_arr = array();
switch($mime) {
case 'image/jpg':
$ext = '.jpg';
// create a new image from file
$vir_img = @imagecreatefromjpeg($temp_file);
break;

case 'image/jpeg':
$ext = '.jpeg';
// create a new image from file
$vir_img = @imagecreatefromjpeg($temp_file);
break;

case 'image/png':
$ext = '.png';
// create a new image from file
$vir_img = @imagecreatefrompng($temp_file);
break;

case 'image/gif':
$ext = '.gif';
// create a new image from file
$vir_img = @imagecreatefromgif($temp_file);
break;
default:
@unlink($temp_file);
return;
}
$vir_img_arr['ext'] = $ext;
$vir_img_arr['img'] = $vir_img;
return $vir_img_arr;
}

function uploadImageFile() {

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
/*Configuration part*/
extract($_POST);
$desired_width = 200; //desired image result width
$desired_height = 200; //desired image result height
$img_quality = 100;
$upload_dir = 'cache/';

if ($_FILES) {
$file = $_FILES['image_file'];
if (! $file['error'] && $file['size'] < 350 * 1024) { if (is_uploaded_file($file['tmp_name'])) { // unique name of the file $temp_file = $upload_dir. md5(time().rand(0,2000)); // upload the file in appropriate folder move_uploaded_file($file['tmp_name'], $temp_file); @chmod($temp_file, 0644); //Again check if the file was uploaded properly without any error if (file_exists($temp_file) && filesize($temp_file) > 0) {
$file_size_arr = getimagesize($temp_file); // get the image detail
if (!$file_size_arr) {
@unlink($temp_file); //if file size array not exits then delete it
return;
}
$mime = $file_size_arr['mime'];
$virtual_img_arr = get_virtual_img($mime,$temp_file);
$virtual_img = $virtual_img_arr['img'];
$virtual_img_ext = $virtual_img_arr['ext'];
// create a new true color image
$true_color_img = @imagecreatetruecolor( $desired_width, $desired_height );

// copy and resize part of an image with resampling
imagecopyresampled($true_color_img, $virtual_img, 0, 0, (int)$x1, (int)$y1, $desired_width, $desired_height, (int)$w, (int)$h);

// define a result image filename
$result = $temp_file . $virtual_img_ext;

// upload resultant file to the folder
imagejpeg($true_color_img, $result, $img_quality);
@unlink($temp_file); //delete the main temporary uploaded file

return $result;
}
}
}
}
}
}

$cropped_img = uploadImageFile();
echo '</pre>
<h1>This is the cropped Image saved in cache folder.</h1>
<h1>
<img src="'.$cropped_img.'" alt="" />';

So this was the tutorial about ‘Crop An Image Using Jquery and PHP’

25 Responses to “Crop An Image And Upload Using Jquery, HTML5 and PHP”
  1. Kumar says:

    Hi,

    Thanks for such a nice tutorial. Is there a way to crop and upload multiple images with preview in single form page using this same approach. Please help me….

    • yes you can do that but you have to make some changes in this code.

      • kumar says:

        Hi,
        I am trying to crop and upload two images in single form page using two separate input elements. But when uploading images, i am not getting exact view of images as shown in preview selection. what necessary changes i need to do to in upload php script. please guide me…..

  2. mark says:

    thanks for the nice tuts but there are no files in your download link

  3. anjil panchal says:

    Great..
    Thanks a lot

  4. Is there any way to preserve the aspect ratio, or force an aspect ratio that matches the file size you want? For instance, if I want all photos to be 200px x 300px, I would like the crop frame to only allow 2×3 aspect ratio sizing and not squish the image when selecting. Is there any way to do that? Thanks so much for making this awesome tool!

  5. hiren says:

    Hi,
    great article.
    thanks a lot.

    I have a quick question

    is that possible to the picture you are changing should ALREADY have a editable crop box like google / google plus….

  6. Ashish Tyagi says:

    Hi Manish
    Can you update the program so that the preview image should appear in the pop-up box with upload button, rather than in the same page. Thanks

    • Do you also want upload button on the popup???????

      • Ashish Tyagi says:

        I would really appreciate if you can put the upload button on the pop-up box. My email is [email protected] . Please email me. I am actually new to the jquery and could not achieve it and I am using your work for community help. So if you can help me I would let the people know and they will thank you. I will explain you everything if you can email me your number.

        Thanks
        Ashish Tyagi

  7. reden says:

    great one! however i have a question….

    var selectedImg = $(‘#image_file’)[0].files[0];

    this is having an error such “0.files.0 is null or not an object”

    IE could not display the image file selected because of the error mentioned.

  8. Reden says:

    What happened to my post ?? got removed ???

    question still remained.

    var selectedImg = $(‘#image_file’)[0].files[0];

    this part is having an error once an image is selected in either of the browsers which says
    ” ’0.files.0′ is null or not an object ”

    IE8 could not display the image due to the error. while firefox and chrome displays the image selected although the error is still there.

    • does your IE browser support HTML 5. Which IE are you using?????????

      • Ashish Tyagi says:

        Hi Manish
        I am still waiting for you response and yes my browser is supporting HTML5 and I have not problem with that. All I am not able to achieve is cropping image in the jquery dialog box and uploading multiple images ( I am trying to upload 4 image from the same page). You can reach me at my email: [email protected] and I will explain you the details.

        Thanks
        Ashish Tyagi

  9. Bhalchandra says:

    Hey,

    Thanks a lot for this article. I was looking for a long to accomplish this on jquery dialog but could not able to find any relevant article on the same. Your post helped me to accomplish the same.

    Thanks a lot.

  10. Ashish Tyagi says:

    I don’t know why but my previous comments has been deleted from the website.

    Ashish

  11. Rahul says:

    Hi i have same problem like Reden says that HTML 5 is not working for IE .Your code is not working for IE so how can i embedded your code for IE.

    Error is ” ’0.files.0′ is null or not an object ”

    on line var selectedImg = $(‘#image_file’)[0].files[0];

    PLZ help

  12. Ashish Tyagi says:

    How to enable this program for multiple files.

  13. cool says:

    great tutorial! can you add a functionality upload the image in mysql database in your other version. thanks!

  14. Tousif says:

    Hey there is a bug!
    when we upload a new image I mean browse for second time, it doesn’t display the correct coordinates in the image preview box
    I think it stores the width and height of previous image due to which not work correctly.