Image upload and crop is an important feature of web applications. This feature is mainly used in user sections to allow users to upload and crop their profile picture before save to the database. The image crop before save is very user friendly feature as it allow users to resize picture to display correctly and also save memory.
So if you’re thinking about implementing image upload and crop functionality in your application, then you’re here at the right place. In this tutorial, you will you will learn how implement Image Upload and Crop in Bootstrap Modal using jQuery and PHP.
We will cover this tutorial in easy steps to implement live demo of image upload and crop functionality using jQuery, PHP and MySQL.
Also, read:
- Upload Multiple Images with jQuery Ajax and PHP
- Upload Multiple Files in CodeIgniter
- AWS S3 File Upload in Golang
So let’s implement image upload and crop in modal example with jQuery, PHP and MySQL. The major files are:
- index.php
- image_crop_save.js
- change_photo.php
- User.php: Class to hold user methods.
Step1: Create MySQL Database Table
As we will create live example to upload and crop user profile picture and save into database table, so first we will create MySQL database table user_profile
using following table create SQL query.
CREATE TABLE `user_profile` ( `id` int(11) NOT NULL, `name` varchar(255) NOT NULL, `email` varchar(255) NOT NULL, `phone` varchar(255) NOT NULL, `photo` varchar(255) NOT NULL, `skills` varchar(255) NOT NULL, `website` varchar(255) NOT NULL, `designation` varchar(255) NOT NULL, `city` varchar(255) NOT NULL, `country` varchar(255) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
We will store a user record to upload and change user profile picture. We will use below insert SQL statment to insert record into table.
INSERT INTO `user_profile` (`id`, `name`, `email`, `phone`, `photo`, `skills`, `website`, `designation`, `city`, `country`) VALUES (1, 'Jhon Smith', 'smith@webdamn.com', '1234567890', '', 'PHP, MySQL, JavaScript', 'abc.com', 'Web developer', 'Newyork', 'USA');
Step2: Include Bootstrap, jQuery Files
We will include required Boostrap, jQuery and CSS files. As we will use jquery.imgareaselect.js
plugin to select and crop image, so we will include plugin files. We will also include CSS files.
<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"> <link rel="stylesheet" href="css/style.css"> <script src="js/image_crop_save.js"></script>
Step3: Display User Profile with Picture
In index.php
file, we will display user profile details with profile picture by calling getUser()
method from class User.php
. We will a Bootstrap modal with form to upload image and crop in modal.
<div class="container emp-profile"> <div class="row"> <div class="col-md-4"> <div class="profile-img"> <img id="profilePhoto" data-src="images/<?php echo $user['photo']; ?>" data-holder-rendered="true" src="images/<?php echo $user['photo']; ?>"/> <div class="file btn btn-lg btn-primary" id="changeProfilePhoto"> <?php echo $uploadText; ?> </div> </div> </div> <div class="col-md-6"> <div class="profile-head"> <h5><?php echo $user['name']; ?></h5> <h6><?php echo $user['designation']; ?></h6> <ul class="nav nav-tabs" id="myTab" role="tablist"> <li class="nav-item"> <a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">About</a> </li> </ul> </div> <div class="col-md-8"> <div class="tab-content profile-tab" id="myTabContent"> <div class="show active" id="home" role="tabpanel" aria-labelledby="home-tab"> <div class="row"> <div class="col-md-6"> <label>Name</label> </div> <div class="col-md-6"> <p><?php echo $user['name']; ?></p> </div> </div> <div class="row"> <div class="col-md-6"> <label>Email</label> </div> <div class="col-md-6"> <p><?php echo $user['email']; ?></p> </div> </div> <div class="row"> <div class="col-md-6"> <label>Phone</label> </div> <div class="col-md-6"> <p><?php echo $user['phone']; ?></p> </div> </div> <div class="row"> <div class="col-md-6"> <label>Profession</label> </div> <div class="col-md-6"> <p><?php echo $user['designation']; ?></p> </div> </div> <div class="row"> <div class="col-md-6"> <label>City</label> </div> <div class="col-md-6"> <p><?php echo $user['city']; ?></p> </div> </div> <div class="row"> <div class="col-md-6"> <label>Country</label> </div> <div class="col-md-6"> <p><?php echo $user['country']; ?></p> </div> </div> </div> </div> </div> </div> <div class="col-md-2"> <input type="submit" class="profile-edit-btn" name="btnAddMore" value="Edit Profile"/> </div> </div> <div class="row"> <div class="col-md-4"> <div class="profile-work"> <p>Website</p> <a href="<?php echo $user['website']; ?>" rel="nofollow" target="_blank"><?php echo $user['website']; ?></a><br/> <p>Skills</p> <a href=""><?php echo $user['skills']; ?></a><br/> </div> </div> </div> </div> <div id="changeProfilePhotoModal" 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 Photo</h3> </div> <div class="modal-body"> <form id="cropImage" method="post" enctype="multipart/form-data" action="change_photo.php"> <strong>Upload Image:</strong> <br><br> <input type="file" name="profileImage" id="profileImage" /> <input type="hidden" name="hdn-profile-id" id="hdn-profile-id" value="<?php echo $user['id']; ?>" /> <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="imageName" value="" id="imageName" /> <div id='previewProfilePhoto'></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="savePhoto" class="btn btn-primary">Crop & Save</button> </div> </div> </div> </div>
Step4: Upload Image and Crop in Modal
In image_crop_save.js
file, we will show image upload modal and handle image upload with image crop.
$('#changeProfilePhoto').on('click', function(e){ $('#changeProfilePhotoModal').modal({show:true}); }); $('#profileImage').on('change', function() { $("#previewProfilePhoto").html(''); $("#previewProfilePhoto").html('Uploading....'); $("#cropImage").ajaxForm( { target: '#previewProfilePhoto', success: function() { $('img#photo').imgAreaSelect({ aspectRatio: '1:1', onSelectEnd: getSizes, }); $('#imageName').val($('#photo').attr('file-name')); } }).submit(); });
Step5: Handle Image Save
In image_crop_save.js
file, we will also handle cropped image save functionality by calling saveCropImage()
function with save
action to change_photo.php
file.
$('#savePhoto').on('click', function(e){ e.preventDefault(); params = { targetUrl: 'change_photo.php?action=save', action: 'save', x_axis: $('#hdn-x1-axis').val(), y_axis : $('#hdn-y1-axis').val(), x2_axis: $('#hdn-x2-axis').val(), y2_axis : $('#hdn-y2-axis').val(), thumb_width : $('#hdn-thumb-width').val(), thumb_height:$('#hdn-thumb-height').val() }; saveCropImage(params); });
In function saveCropImage()
, will make ajax request to change_photo.php
file with image details and get saved image details.
function saveCropImage(params) { $.ajax({ url: params['targetUrl'], cache: false, dataType: "html", data: { action: params['action'], id: $('#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'], imageName :$('#imageName').val() }, type: 'Post', success: function (response) { $('#changeProfilePhotoModal').modal('hide'); $(".imgareaselect-border1,.imgareaselect-border2,.imgareaselect-border3,.imgareaselect-border4,.imgareaselect-border2,.imgareaselect-outer").css('display', 'none'); console.log(response); $("#profilePhoto").attr('src', response); $("#previewProfilePhoto").html(''); $("#profileImage").val(); $("#changeProfilePhoto").text('Change Photo'); }, error: function (xhr, ajaxOptions, thrownError) { alert('status Code:' + xhr.status + 'Error Message :' + thrownError); } }); }
Step6: Implement Upload Image and Crop Preview
We will implement method changeProfilePhoto()
in class User.php
to display upload image preview with crop image.
public function changeProfilePhoto() { $post = isset($_POST) ? $_POST: array(); $maxWidth = "500"; $userId = isset($post['hdn-profile-id']) ? intval($post['hdn-profile-id']) : 0; $path = 'images/tmp'; $validFormats = array("jpg", "png", "gif", "jpeg"); $picName = $_FILES['profileImage']['name']; $size = $_FILES['profileImage']['size']; if(strlen($picName)) { list($txt, $ext) = explode(".", $picName); if(in_array($ext,$validFormats)) { if($size<(1024*1024)) { $actualImageName = 'avatar' .'_'.$userId .'.'.$ext; $filePath = $path .'/'.$actualImageName; $tmp = $_FILES['profileImage']['tmp_name']; if(move_uploaded_file($tmp, $filePath)) { $width = $this->getWidth($filePath); $height = $this->getHeight($filePath); if ($width > $maxWidth){ $scale = $maxWidth/$width; $uploaded = $this->resizeImage($filePath,$width,$height,$scale, $ext); } else { $scale = 1; $uploaded = $this->resizeImage($filePath,$width,$height,$scale, $ext); } echo "<img id='photo' file-name='".$actualImageName."' 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; }
Step7: Save Cropped Image to Server and MySQL Database Table
We will implement method saveProfilePhoto()
in class User.php
to save cropped profile picture to images
directory and into MySQL database table.
public function saveProfilePhoto() { $post = isset($_POST) ? $_POST: array(); $userId = isset($post['id']) ? intval($post['id']) : 0; $path = 'images/tmp/'.$_POST['imageName']; $tmpWidth = 300; $tmpHeight = 300; if(isset($_POST['t']) and $_POST['t'] == "ajax") { extract($_POST); $imagePath = 'images/'.$_POST['imageName']; $ratio = ($tmpWidth/$w1); $nw = ceil($w1 * $ratio); $nh = ceil($h1 * $ratio); $nimg = imagecreatetruecolor($nw,$nh); $imgSrc = imagecreatefromjpeg($path); imagecopyresampled($nimg,$imgSrc,0,0,$x1,$y1,$nw,$nh,$w1,$h1); imagejpeg($nimg,$imagePath,90); } $updateQuery = " UPDATE ".$this->userTable." SET photo = '".$_POST['imageName']."' WHERE id = '$userId'"; mysqli_query($this->dbConnect, $updateQuery); $saveImagePath = $imagePath.'?'.time(); echo $saveImagePath; exit(0); }
You may also like:
- User Management System with PHP & MySQL
- Datatables Add Edit Delete with Ajax, PHP & MySQL
- Build Helpdesk System with jQuery, PHP & MySQL
- Build Online Voting System with PHP & MySQL
- School Management System with PHP & MySQL
- DataTables Add Edit Delete with CodeIgniter
- Create RESTful API using CodeIgniter
- Build Reusable Captcha Script with PHP
- Product Search Filtering using Ajax, PHP & MySQL
- Image Upload and Crop in Modal with jQuery, PHP & MySQL
- Build Push Notification System with PHP & MySQL
- Project Management System with PHP and MySQL
- Hospital Management System with PHP & MySQL
- Build Newsletter System with PHP and MySQL
- Skeleton Screen Loading Effect with Ajax and PHP
- Build Discussion Forum with PHP and MySQL
- Customer Relationship Management (CRM) System with PHP & MySQL
- Online Exam System with PHP & MySQL
- Expense Management System with PHP & MySQL
You can view the live demo from the Demo link and can download the script from the Download link below.
Demo Download
Hello.
Cannot see any image selector for’ cropping on the demo