Вырезаем изображение с помощью jQuery и PHP
Допустим Ваш клиент загрузил изображение в CMS и сказал, что ему оно не нравится, и он хотел бы его изменить. Этот сценарий знают практически все. В этом статье мы опишем механизм вырезки изображения, и всё, что Вашему клиенту останется сделать, так это выделить нужный фрагмент и нажать на кнопку.
После того, как мы вырежем изображение через PHP GD, сохраним то, что у нас получилось на диске.
Мы будем больше уделять внимание части редактирования изображения, полагая, что клиент предварительно его загрузил:
<p>Выделите необходимый фрагмент.</p>
<p>
<img id="photo" src="photo.jpg" alt="" title="" style="margin: 0 0 0 10px;" />
</p>
У нас есть изображение с id и стилем. В нашем деле нам поможет плагин jQuery ImgAreaSelect, ну для того чтобы не изобретать велосипед.
Подключаем библиотеки и таблицы стилей в разделе head:
<link rel="stylesheet" type="text/css" href="css/imgareaselect-default.css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="scripts/jquery.imgareaselect.pack.js"></script>
Теперь Вы готовы к «волшебству»! Мы покажем пользователю небольшое превью, которое реализуем через jQuery
$(document).ready(function () {
$('<div><img src="photo.jpg" style="position: relative;" /><div>') .css({
float: 'left',
position: 'relative',
overflow: 'hidden',
width: '100px',
height: '100px'
}) .insertAfter($('#photo'));
});
Данный код выведет блок размером 100x на 100px. Теперь реализуем функциональность, отвечающую за вырезание
$(document).ready(function () {
$('<div><img src="photo.jpg" style="position: relative;" /><div>') .css({
float: 'left',
position: 'relative',
overflow: 'hidden',
width: '100px',
height: '100px'
}) .insertAfter($('#photo'));
$('#photo').imgAreaSelect({
aspectRatio: '1:1',
handles: true,
onSelectChange: preview
});
});
Мы добавили вызов нашего плагина, передали несколько параметров и функцию обратного вызова, которая отобразит выделенный нами фрагмент в отдельном блоке. Вот как она выглядит:
function preview(img, selection) {
var scaleX = 100 / (selection.width || 1);
var scaleY = 100 / (selection.height || 1);
$('#photo + div > img').css({
width: Math.round(scaleX * 600) + 'px',
height: Math.round(scaleY * 400) + 'px',
marginLeft: '-' + Math.round(scaleX * selection.x1) + 'px',
marginTop: '-' + Math.round(scaleY * selection.y1) + 'px'
});
}
Тут пожалуй мы немного объясним. Наш плагин отправит 2 параметра анонимной функции, изображение и координаты выделения. Выделение представлено у нас объектом, содержащим ширину, высоту и границы.
Затем мы получаем новые координаты и, изменяя значения свойств CSS нашего презентационного блока, показываем отдельный фрагмент фотки. Ну ни круто ли?
Ну и что теперь? Что дальше? Круть конечно полнейшая, но как нам сохранить выделенное изображение. Для этого нам необходимо послать соответствующие координаты в файл PHP. Чтобы нам было проще, создадим форму, в которую запишем соответствующие данные для отправки.
Давайте же создадим формы ниже нашего изображения:
<p>
<img id="photo" src="photo.jpg" alt="" title="" style="margin: 0 0 0 10px;" />
</p>
<form action="crop.php" method="post">
<input type="hidden" name="x1" value="" />
<input type="hidden" name="y1" value="" />
<input type="hidden" name="x2" value="" />
<input type="hidden" name="y2" value="" />
<input type="hidden" name="w" value="" />
<input type="hidden" name="h" value="" />
<input type="submit" value="Crop" />
</form>
Теперь напишем JavaScript фрагмент, который будет заполнять поля нашей формы. Код примерно такой
function preview(img, selection) {
var scaleX = 100 / (selection.width || 1);
var scaleY = 100 / (selection.height || 1);
$('#photo + div > img').css({
width: Math.round(scaleX * 600) + 'px',
height: Math.round(scaleY * 400) + 'px',
marginLeft: '-' + Math.round(scaleX * selection.x1) + 'px',
marginTop: '-' + Math.round(scaleY * selection.y1) + 'px'
});
}
$(document).ready(function () {
$('<div><img src="photo.jpg" style="position: relative;" /><div>') .css({
float: 'left',
position: 'relative',
overflow: 'hidden',
width: '100px',
height: '100px'
}) .insertAfter($('#photo'));
$('#photo').imgAreaSelect({
aspectRatio: '1:1',
handles: true,
onSelectChange: preview,
onSelectEnd: function ( image, selection ) {
$('input[name=x1]').val(selection.x1);
$('input[name=y1]').val(selection.y1);
$('input[name=x2]').val(selection.x2);
$('input[name=y2]').val(selection.y2);
$('input[name=w]').val(selection.width);
$('input[name=h]').val(selection.height);
}
});
});
Когда вы выделили необходимую область (отпустили кнопку мыши), функция обратного вызова вставит 4 координаты в поля нашей формы. После нажатия на кнопку Crop, эти данные отправляются в PHP файл crop.php, который вырежет выбранный фрагмент и сохранит его на диске. Содержимое файла crop.php
// оригинальное изображение
$filename = 'photo.jpg';
//die(print_r($_POST));
$new_filename = 'photo1.jpg';
// получаем размеры изображения
list($current_width, $current_height) = getimagesize($filename);
// координаты x и y оригинального изображение, где мы
// будем вырезать фрагмент, по данным, берущимся из формы
$x1 = $_POST['x1'];
$y1 = $_POST['y1'];
$x2 = $_POST['x2'];
$y2 = $_POST['y2'];
$w = $_POST['w'];
$h = $_POST['h'];
//die(print_r($_POST));
// финальные размеры изображения
$crop_width = 100;
$crop_height = 100;
// создаём маленькое изображение
$new = imagecreatetruecolor($crop_width, $crop_height);
// создаём оригинальное изображение
$current_image = imagecreatefromjpeg($filename);
//вырезаем
imagecopyresampled($new, $current_image, 0, 0, $x1, $y1, $crop_width, $crop_height, $w, $h);
// создаём новое изображение
imagejpeg($new, $new_filename, 95);