بارگذاری عکس و برش (CROP) آن با PHP و jQuery

Image Upload and Crop in Modal with jQuery, PHP & MySQL

29 آبان 1400
image-upload-and-crop-with-jquery-php-min

سلام به همران همیشگی روکسو. در این مقاله قصد ساخت سیستمی را داریم که در آن کاربر تصویر حساب کاربری (پروفایل) خود را تغییر می دهد. تفاوتی این سیستم دارد این است که کاربر می تواند تصویر خود را قبل از ارسال برش (CROP) دهد.

ما در این آموزش از زبان برنامه نویسی PHP و از پایگاه داده MYSQL استفاده می کنیم که شما می توانید این دو را با نصب برنامه xampp به دست آورید.

قبل از شروع آموزش، کاری که باید انجام دهید این است که دو کتابخانه زیر را دانلود کنید و در محل برنامه نویسی خود پوشه ای با نام dist_files ایجاد کنید و در این پوشه انتقال دهید:

jquery.imgareaselect.min.js

jquery.form.min.js

فایل php.ini خود را باز کنید برای یافتن این فایل تابع ;()phpinfo را در یک فایل php اجرا کنید. پس از یافتن فایل، آن را با یک ویرایشگر باز کنید. extension=gd در آن بیابید و ; اول آن را حذف کنید.

قدم اول: ساخت جدول پایگاه داده

ما باید یک پایگاه داده ایجاد و در آن جدولی به نام user_profile ایجاد کنیم.

در مرورگر خود به آدرس http://localhost/phpmyadmin بروید. سپس بر روی database کلیک کرده و یک نام برای پایگاه داده خود انتخاب کنید. بر روی create کلیک کنید و در نهایت بعد از ساخت پایگاه داده به سربرگ SQL رفته و دستورات زیر را وارد کنید تا جدول user_profile ساخته شود:

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;

و برای مقداردهی آن دستورات زیر را وارد کنید:

INSERT INTO `user_profile` (`id`, `name`, `email`, `phone`, `photo`, `skills`, `website`, `designation`, `city`, `country`) VALUES
(1, 'Jhon Smith', 'admin@admin.com', '1234567890', '', 'PHP, MySQL, JavaScript', 'abc.com', 'Web developer', 'Newyork', 'USA');

قدم دوم: نشان دادن تصویر حساب کاربری

برای آن که بتوانیم اطلاعات کاربران را دریافت کنیم، نیاز به اتصال به پایگاه داده داریم.

یک فایل با نام User.php ایجاد کنید و دستورات زیر را وارد کنید:

<?php
class User {
    private $host  = 'localhost';
    private $user  = 'root';
    private $password   = "";
    private $database  = "test";
    private $userTable = 'user_profile';    
    private $dbConnect = false;
    public function __construct(){
        if(!$this->dbConnect){ 
            $conn = new mysqli($this->host, $this->user, $this->password, $this->database);
            if($conn->connect_error){
                die("Error failed to connect to MySQL: " . $conn->connect_error);
            }else{
                $this->dbConnect = $conn;
            }
        }
    }	
    public function getUser() {		
        $sqlQuery = "
            SELECT id, name, email, phone, photo, skills, website, designation, city, country
            FROM ".$this->userTable." 
            WHERE id = 1";		$result = mysqli_query($this->dbConnect, $sqlQuery);		
        $data= mysqli_fetch_array($result, MYSQLI_ASSOC);
        return $data;
    }	
    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;
    }	
    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);    
    }    	
    public function resizeImage($image,$width,$height,$scale, $ext) {
        $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;
    }	
    public function getHeight($image) {
        $sizes = getimagesize($image);
        $height = $sizes[1];
        return $height;
    }	
    public function getWidth($image) {
        $sizes = getimagesize($image);
        $width = $sizes[0];
        return $width;
    }	
}

و در ادامه یک فایل با نام index.php ایجاد و دستورات زیر را وارد کنید:

<?php
include("User.php");
$userObj = new User();
$user = $userObj->getUser();
if ($user['photo'] == '') {
    $user['photo'] = 'default.jpg';
    $uploadText = "Upload Photo";
} else {
    $uploadText = "Change Photo";
}
include('inc/header.php');
?>
<title> Demo of Image Upload and Image Crop in Modal with PHP and jQuery</title>
<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>
<div class="container">
    <h2>Example: Image Upload and Image Crop in Modal with PHP and jQuery</h2>
    <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">&times;</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>
</div>
<?php include('inc/footer.php'); ?>

یک پوشه با نام js ایجاد و در آن یک فایل با نام image_crop_save.js ایجاد کرده و دستورات زیر را وارد کنید:

$(document).ready(function(){	
    $('#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();

    });	
    $('#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);
    });   
    function getSizes(img, obj){
        var x_axis = obj.x1;
        var x2_axis = obj.x2;
        var y_axis = obj.y1;
        var y2_axis = obj.y2;
        var thumb_width = obj.width;
        var thumb_height = obj.height;
        if(thumb_width > 0) {
            $('#hdn-x1-axis').val(x_axis);
            $('#hdn-y1-axis').val(y_axis);
            $('#hdn-x2-axis').val(x2_axis);
            $('#hdn-y2-axis').val(y2_axis);
            $('#hdn-thumb-width').val(thumb_width);
            $('#hdn-thumb-height').val(thumb_height);
        } else {
            alert("Please select portion..!");
        }
    }   
    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);
            }
        });
    }
});

دستورات بالا برای برش عکس استفاده می شود. در ادامه یک پوشه با نام inc ایجاد کرده و در آن دو فایل با نام های footer.php - header.php ایجاد کنید. در فایل header.php دستورات زیر را وارد کنید

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<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>
<!-- jQuery -->

و برای footer.php:

<div class="insert-post-ads1" style="margin-top:20px;">

</body>
</html>

را اضافه کنید. یک پوشه با نام images ایجاد کنید که در آن تصاویر ذخیره شود. در این پوشه یک پوشه دیگر با نام tmp  ایجاد کنید.

در ادامه باید به برنامه خود style بدهیم در پوشه dist_files یک فایل با نام imgareaselect.css ایجاد و دستوارت زیر را وارد کنید:

/*
 * imgAreaSelect animated border style
 */

.imgareaselect-border1 {
    background: url(border-anim-v.gif) repeat-y left top;
}

.imgareaselect-border2 {
    background: url(border-anim-h.gif) repeat-x left top;
}

.imgareaselect-border3 {
    background: url(border-anim-v.gif) repeat-y right top;
}

.imgareaselect-border4 {
    background: url(border-anim-h.gif) repeat-x left bottom;
}

.imgareaselect-border1, .imgareaselect-border2,
.imgareaselect-border3, .imgareaselect-border4 {
    filter: alpha(opacity=50);
    opacity: 0.5;
}

.imgareaselect-handle {
    background-color: #fff;
    border: solid 1px #000;
    filter: alpha(opacity=50);
    opacity: 0.5;
}

.imgareaselect-outer {
    background-color: #000;
    filter: alpha(opacity=50);
    opacity: 0.5;
}

.imgareaselect-selection {
}

دستورات بالا style برش کننده عکس می باشد.

و در نهایت یک پوشه به نام css و در آن یک فایل به نام style.css ایجاد کنید و دستورات زیر را وارد کنید:

body{
    background: -webkit-linear-gradient(left, #3931af, #00c6ff);
}
.emp-profile{
    padding: 3%;
    margin-top: 3%;
    margin-bottom: 3%;
    border-radius: 0.5rem;
    background: #fff;
}
.profile-img{
    text-align: center;
}
.profile-img img{
    width: 70%;
    height: 100%;
}
.profile-img .file {
    position: relative;
    overflow: hidden;
    margin-top: -20%;
    width: 70%;
    border: none;
    border-radius: 0;
    font-size: 15px;
    background: #212529b8;
}
.profile-img .file input {
    position: absolute;
    opacity: 0;
    right: 0;
    top: 0;
}
.profile-head h5{
    color: #333;
}
.profile-head h6{
    color: #0062cc;
}
.profile-edit-btn{
    border: none;
    border-radius: 1.5rem;
    width: 70%;
    padding: 2%;
    font-weight: 600;
    color: #6c757d;
    cursor: pointer;
}
.proile-rating{
    font-size: 12px;
    color: #818182;
    margin-top: 5%;
}
.proile-rating span{
    color: #495057;
    font-size: 15px;
    font-weight: 600;
}
.profile-head .nav-tabs{
    margin-bottom:5%;
}
.profile-head .nav-tabs .nav-link{
    font-weight:600;
    border: none;
}
.profile-head .nav-tabs .nav-link.active{
    border: none;
    border-bottom:2px solid #0062cc;
}
.profile-work{
    padding: 0px 0px 0px 50px;    
}
.profile-work p{
    font-size: 12px;
    color: #818182;
    font-weight: 600;
    margin-top: 10%;
}
.profile-work a{
    text-decoration: none;
    color: #495057;
    font-weight: 600;
    font-size: 14px;
}
.profile-work ul{
    list-style: none;
}
.profile-tab label{
    font-weight: 600;
}
.profile-tab p{    
    color: #0062cc;
}

امیدوارم این آموزش برای شما مفید بوده باشد.


منبع: وب سایت webdamn

نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.