Image Upload and Crop in Modal with PHP and jQuery

Image Upload and Crop in Modal with PHP and jQuery

As I have received many requests from my readers to write on image upload and crop in modal box in PHP. Image upload and crop is the most important feature of any web project. We can provide great user experience to the end users to upload and change their profile pictures in a modal and also enable them to crop uploaded profile picture in same modal.

So here in this tutorial, you will learn how to implement image upload and crop in a modal box using PHP and jQuery. We will cover this tutorial in easy steps to implement live demo of image upload and crop. We will also allow to download complete source code of live demo.



We will use following library with this Example:

  • jQuery Library : This is a base library to support other jQuery plugin

  • Boostrap 3 : Bootstrap used to create page layout

  • Imgareaselect : This plugin used to define crop co-ordinate and crop image.

  • Ajax form : This jQuery plugin used to handle submit form Ajax manner.


We will use following files with this Example

  • index.php : This is a main file that create HTML layout to show change image button with image preview.

  • change_pic.php : This file is responsible to all server side functionality like image cropping and saving

  • functions.js : This file contains JavaScript code and functions related to cropped image size and save cropped images.


Steps to implement image upload and crop in a modal using PHP and jQuery:

Step 1: First of all, we will include all necessary library files and JavaScript in head in index.php.
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="dist_files/jquery.imgareaselect.js" type="text/javascript"></script>
<script src="dist_files/jquery.form.js"></script>
<link rel="stylesheet" href="dist_files/imgareaselect.css">
<script src="functions.js"></script>


Step 2: Now we will create HTML in index.php to display Change Profile Picture button and image preview section to display saved profile picture.
<div>
<img class="img-circle" id="profile_picture" height="128" data-src="default.jpg" data-holder-rendered="true" style="width: 140px; height: 140px;" src="default.jpg"/>
<br><br>
<a type="button" class="btn btn-primary" id="change-profile-pic">Change Profile Picture</a>
</div>


Step 3: Now we will create model box in index.php for image upload and crop functionality.

<div id="profile_pic_modal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3>Change Profile Picture</h3>
</div>
<div class="modal-body">
<form id="cropimage" method="post" enctype="multipart/form-data" action="change_pic.php">
<strong>Upload Image:</strong> <br><br>
<input type="file" name="profile-pic" id="profile-pic" />
<input type="hidden" name="hdn-profile-id" id="hdn-profile-id" value="1" />
<input type="hidden" name="hdn-x1-axis" id="hdn-x1-axis" value="" />
<input type="hidden" name="hdn-y1-axis" id="hdn-y1-axis" value="" />
<input type="hidden" name="hdn-x2-axis" value="" id="hdn-x2-axis" />
<input type="hidden" name="hdn-y2-axis" value="" id="hdn-y2-axis" />
<input type="hidden" name="hdn-thumb-width" id="hdn-thumb-width" value="" />
<input type="hidden" name="hdn-thumb-height" id="hdn-thumb-height" value="" />
<input type="hidden" name="action" value="" id="action" />
<input type="hidden" name="image_name" value="" id="image_name" />
<div id='preview-profile-pic'></div>
<div id="thumbs" style="padding:5px; width:600p"></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" id="save_crop" class="btn btn-primary">Crop & Save</button>
</div>
</div>
</div>
</div>


Step 4: Now will show the model box using jQuery when click on Change Profile Picture button.
jQuery('#change-profile-pic').on('click', function(e){
jQuery('#profile_pic_modal').modal({show:true});
});


Step 5: Now we will show the image for crop process on bootstrap modal box and also handle form submit using jQuery form plguin.

jQuery('#profile-pic').on('change', function() {
jQuery("#preview-profile-pic").html('');
jQuery("#preview-profile-pic").html('Uploading....');
jQuery("#cropimage").ajaxForm(
{
target: '#preview-profile-pic',
success: function() {
jQuery('img#photo').imgAreaSelect({
aspectRatio: '1:1',
onSelectEnd: getSizes,
});
jQuery('#image_name').val(jQuery('#photo').attr('file-name'));
}
}).submit();
});


Step 6: Now we will handle image crop and call saveCropImage() ajax method to save image on hard disk storage when click on Crop & Save button.

jQuery('#save_crop').on('click', function(e){
e.preventDefault();
params = {
targetUrl: 'change_pic.php?action=save',
action: 'save',
x_axis: jQuery('#hdn-x1-axis').val(),
y_axis : jQuery('#hdn-y1-axis').val(),
x2_axis: jQuery('#hdn-x2-axis').val(),
y2_axis : jQuery('#hdn-y2-axis').val(),
thumb_width : jQuery('#hdn-thumb-width').val(),
thumb_height:jQuery('#hdn-thumb-height').val()
};
saveCropImage(params);
});


Step 7: JavaScript function saveCropImage() to save cropped images.
function saveCropImage(params) {
jQuery.ajax({
url: params['targetUrl'],
cache: false,
dataType: "html",
data: {
action: params['action'],
id: jQuery('#hdn-profile-id').val(),
t: 'ajax',
w1:params['thumb_width'],
x1:params['x_axis'],
h1:params['thumb_height'],
y1:params['y_axis'],
x2:params['x2_axis'],
y2:params['y2_axis'],
image_name :jQuery('#image_name').val()
},
type: 'Post',
success: function (response) {
jQuery('#profile_pic_modal').modal('hide');
jQuery(".imgareaselect-border1,.imgareaselect-border2,.imgareaselect-border3,.imgareaselect-border4,.imgareaselect-border2,.imgareaselect-outer").css('display', 'none');
jQuery("#profile_picture").attr('src', response);
jQuery("#preview-profile-pic").html('');
jQuery("#profile-pic").val();
},
error: function (xhr, ajaxOptions, thrownError) {
alert('status Code:' + xhr.status + 'Error Message :' + thrownError);
}
});
}


Step 8: Now handle upload profile picture at server side to upload image/change image on server and also handle save changed picture into MySQL database table in file change_pic.php.

<?php
/* Get post details */
$post = isset($_POST) ? $_POST: array();
switch($post['action']) {
case 'save' :
saveProfilePic();
saveProfilePicTmp();
break;
default:
changeProfilePic();
}
/* Function to change profile picture */
function changeProfilePic() {
$post = isset($_POST) ? $_POST: array();
$max_width = "500";
$userId = isset($post['hdn-profile-id']) ? intval($post['hdn-profile-id']) : 0;
$path = 'images/tmp';
$valid_formats = array("jpg", "png", "gif", "jpeg");
$name = $_FILES['profile-pic']['name'];
$size = $_FILES['profile-pic']['size'];
if(strlen($name)) {
list($txt, $ext) = explode(".", $name);
if(in_array($ext,$valid_formats)) {
if($size < (1024*1024)) { $actual_image_name = 'avatar' .'_'.$userId .'.'.$ext; $filePath = $path .'/'.$actual_image_name; $tmp = $_FILES['profile-pic']['tmp_name']; if(move_uploaded_file($tmp, $filePath)) { $width = getWidth($filePath); $height = getHeight($filePath); //Scale the image if it is greater than the width set above if ($width > $max_width){
$scale = $max_width/$width;
$uploaded = resizeImage($filePath,$width,$height,$scale, $ext);
} else {
$scale = 1;
$uploaded = resizeImage($filePath,$width,$height,$scale, $ext);
}
echo "<img id='photo' file-name='".$actual_image_name."' class='' src='".$filePath.'?'.time()."' class='preview'/>";
}
else
echo "failed";
}
else
echo "Image file size max 1 MB";
}
else
echo "Invalid file format..";
}
else
echo "Please select image..!";
exit;
}
/* Function to update image */
function saveProfilePicTmp() {
$post = isset($_POST) ? $_POST: array();
$userId = isset($post['id']) ? intval($post['id']) : 0;
$path ='\\images\tmp';
$t_width = 300; // Maximum thumbnail width
$t_height = 300; // Maximum thumbnail height
if(isset($_POST['t']) and $_POST['t'] == "ajax") {
extract($_POST);
$imagePath = 'images/tmp/'.$_POST['image_name'];
$ratio = ($t_width/$w1);
$nw = ceil($w1 * $ratio);
$nh = ceil($h1 * $ratio);
$nimg = imagecreatetruecolor($nw,$nh);
$im_src = imagecreatefromjpeg($imagePath);
imagecopyresampled($nimg,$im_src,0,0,$x1,$y1,$nw,$nh,$w1,$h1);
imagejpeg($nimg,$imagePath,90);
}
echo $imagePath.'?'.time();;
exit(0);
}
/* Function to resize image */
function resizeImage($image,$width,$height,$scale) {
$newImageWidth = ceil($width * $scale);
$newImageHeight = ceil($height * $scale);
$newImage = imagecreatetruecolor($newImageWidth,$newImageHeight);
switch ($ext) {
case 'jpg':
case 'jpeg':
$source = imagecreatefromjpeg($image);
break;
case 'gif':
$source = imagecreatefromgif($image);
break;
case 'png':
$source = imagecreatefrompng($image);
break;
default:
$source = false;
break;
}
imagecopyresampled($newImage,$source,0,0,0,0,$newImageWidth,$newImageHeight,$width,$height);
imagejpeg($newImage,$image,90);
chmod($image, 0777);
return $image;
}
/* Function to get image height. */
function getHeight($image) {
$sizes = getimagesize($image);
$height = $sizes[1];
return $height;
}
/* Function to get image width */
function getWidth($image) {
$sizes = getimagesize($image);
$width = $sizes[0];
return $width;
}
?>


Step 9: Now finally save/update changed image path into MySQL database using below PHP function saveProfilePic().

/* Function to handle profile pic update*/
function saveProfilePic(){
include_once("db_connect.php");
$post = isset($_POST) ? $_POST: array();
//Handle profile picture update with MySQL update Query using $options array
if($post['id']){
$sql_query = "SELECT * FROM users WHERE uid = '".mysqli_escape_string($conn, $post['id'])."'";
$resultset = mysqli_query($conn, $sql_query) or die("database error:". mysqli_error($conn));
if(mysqli_num_rows($resultset)) {
$sql_update = "UPDATE users set profile_photo='".mysqli_escape_string($conn,$post['image_name'])."' WHERE uid = '".mysqli_escape_string($conn, $post['id'])."'";
mysqli_query($conn, $sql_update) or die("database error:". mysqli_error($conn));
}
}
}


You can see view the complete running example from the demo link. You can also download complete demo script from below links.

Demo [sociallocker]Download[/sociallocker]

Anda mungkin menyukai postingan ini