Ajax-загрузка и масштабирование изображений в PHP

Сегодня я представлю важный элемент социально-ориентированного сайта, осуществляющий загрузку изображений на сайт и их масштабирование без необходимости перезагрузки текущей страницы с использованием PHP и jQuery.

Эта статья является продолжением предыдущей, я просто включил в неё механизм изменения размера изображений. Этот скрипт может быть очень полезен тем, что экономит место на сервере и трафик. Обратите внимание на демонстрацию:

Загрузить исходники можно отсюда.

Код расположен в трёх каталогах: js, includes и uploads. Структура файлов такова:

includes
-- getExtension.php  
-- compressImage.php 
js
-- jquery.min.js
-- jquery.form.js
uploads
index.php
ajaximageupload.php 
db.php

Код JavaScript

Элемент input типа file помечен идентификатором photoimg, а форма, которой он принадлежит – imageform. Изменение состояние элемента input приводит к отправке формы при помощи jQuery-метода ajaxForm() без перезагрузки страницы. Загруженное изображение предварительно отображается в блоке с идентификатором preview:

<script type="text/javascript" src="http://ajax.googleapis.com/
ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="jquery.form.js"></script>
<script type="text/javascript">
$(document).ready(function() 
{ 

$('body').on('change','#photoimg', function()
 {
var A=$("#imageloadstatus");
var B=$("#imageloadbutton");

$("#imageform").ajaxForm({target: '#preview', 
beforeSubmit:function(){
A.show();
B.hide();
}, 
success:function(){
A.hide();
B.show();
}, 
error:function(){
A.hide();
B.show();
} }).submit();
});

}); 
</script>

Отображение элементов #imageloadstatus и #imageloadbutton зависит от состояния формы.

Для одновременной загрузки нескольких файлов вы можете использовать скрипт jquery.wallform.js вместо jquery.form.js.

index.php

Содержит простую смесь PHP и HTML-кода. Фраза «$session_id=1» является заглушкой для будущего получения идентификатора пользовательской сессии:

<?php
include('db.php');
session_start();
$session_id='1'; // User login session value
?>
<div id='preview'>
</div>
<form id="imageform" method="post" enctype="multipart/form-data" action='ajaximage.php'>
Upload image: 
<div id='imageloadstatus' style='display:none'><img src="loader.gif" alt="Uploading...."/></div>
<div id='imageloadbutton'>
<input type="file" name="photoimg" id="photoimg" />

</div>
</form>

Простая реализация базы данных скрипта

Таблица Users содержит основные данные о пользователе: имя, пароль, адрес электронной почты и фотографию (аватар):

CREATE TABLE `users` (
`uid` int(11) AUTO_INCREMENT PRIMARY KEY,
`username` varchar(255) UNIQUE KEY,
`password` varchar(100),
`email` varchar(255) UNIQUE KEY,
`profile_image` varchar(200)
)

ajaximage.php

Содержит PHP-код, который осуществляет загрузку изображения в каталог uploads. Полученный файл именуется по схеме: timestamp+session_id.extension:

<?php
include('db.php');
session_start();
$session_id='1'; // User session id
$path = "uploads/";

$valid_formats = array("jpg", "png", "gif", "bmp","jpeg","PNG","JPG","JPEG","GIF","BMP");
if(isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST")
{
include_once 'includes/getExtension.php';
$imagename = $_FILES['photoimg']['name'];
$size = $_FILES['photoimg']['size'];
if(strlen($imagename))
{
$ext = strtolower(getExtension($imagename));
if(in_array($ext,$valid_formats))
{
if($size<(1024*1024)) // Image size max 1 MB
{
$actual_image_name = time().$session_id.".".$ext;
$uploadedfile = $_FILES['photoimg']['tmp_name'];

//Re-sizing image. 
include 'includes/compressImage.php';
$widthArray = array(200,100,50); //You can change dimension here.
foreach($widthArray as $newwidth)
{
$filename=compressImage($ext,$uploadedfile,$path,$actual_image_name,$newwidth);
echo "<img src='".$filename."' class='img'/>";
}

//Original Image
if(move_uploaded_file($uploadedfile, $path.$actual_image_name))
{
//Insert upload image files names into user_uploads table
mysqli_query($db,"UPDATE users SET profile_image='$actual_image_name' WHERE uid='$session_id';");
echo "<img src='uploads/".$actual_image_name."' class='preview'>";
}
else
echo "failed";
}
else
echo "Image file size max 1 MB"; 
}
else
echo "Invalid file format.."; 
}
else
echo "Please select image..!";
exit;
}
?>

compressimage.php

Этот модуль отвечает за возвращение изображения к стандартным размерам:

<?php
function compressImage($ext,$uploadedfile,$path,$actual_image_name,$newwidth)
{

if($ext=="jpg" || $ext=="jpeg" )
{
$src = imagecreatefromjpeg($uploadedfile);
}
else if($ext=="png")
{
$src = imagecreatefrompng($uploadedfile);
}
else if($ext=="gif")
{
$src = imagecreatefromgif($uploadedfile);
}
else
{
$src = imagecreatefrombmp($uploadedfile);
}

list($width,$height)=getimagesize($uploadedfile);
$newheight=($height/$width)*$newwidth;
$tmp=imagecreatetruecolor($newwidth,$newheight);
imagecopyresampled($tmp,$src,0,0,0,0,$newwidth,$newheight,$width,$height);
$filename = $path.$newwidth.'_'.$actual_image_name; //PixelSize_TimeStamp.jpg
imagejpeg($tmp,$filename,100);
imagedestroy($tmp);
return $filename;
}
?>

getExtension.php

Здесь хранится функция для получения расширения файла:

function getExtension($str)
{
$i = strrpos($str,".");
if (!$i)
{
return "";
}
$l = strlen($str) - $i;
$ext = substr($str,$i+1,$l);
return $ext;
}

db.php

Здесь хранится конфигурация соединения с базой данных: имя базы данных, имя пользователя, пароль:

<?php
define('DB_SERVER', 'localhost');
define('DB_USERNAME', 'username');
define('DB_PASSWORD', 'password');
define('DB_DATABASE', 'database');
$db = mysqli_connect(DB_SERVER,DB_USERNAME,DB_PASSWORD,DB_DATABASE);
?>

РедакцияПеревод статьи «Ajax Upload and Resize an Image with PHP»