Создание миниатюр на стороне клиента без перезагрузки страницы или немного уличной магии
by Вредный • 25.08.2010 • javascript, jQuery, php, программирование • Комментарии [7]
Сейчас я расскажу вам, как связывал uploadify — плагин, для jQuery для асинхронной загрузки файлов на сервер, прочитать о котором вы можете у меня в заметке «Добавление файлов на сервер без перезагрузки страницы», и плагин jCrop, для ресайзинга изображений на стороне клиента. Я посчитал, что заполнять форму, загружать изображения и делать миниатюры для загруженных файлов легче для пользователей на одной странице. Есть в этой связке нереализованные места, но обо всем поподробнее. Список нужных файлов в конце заметки.
Будем считать, что вы расположили все файлы как в заметке, а теперь мы ее немного расширим. Вот весь javascript на стринице, придется заменить тот, который остался после последней заметки.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | /** * обновляем координаты прямоугольника, миниатюры создающего */ function updateCoords(c) { $('#x').val(c.x); $('#y').val(c.y); $('#w').val(c.w); $('#h').val(c.h); }; /** * чтобы не отправлять нулевые координаты */ function checkCoords() { if (parseInt($('#w').val())) return true; alert('Please select a crop region then press submit.'); return false; }; $(function() { $('form').submit(function(){ $('#files').val($('#response').html()); }); // загрузить файлы $('#upload').click(function(){ $('#uploadify').uploadifyUpload(); return false; }); // асинхронная загрузка $('#uploadify').uploadify({ 'uploader': 'uploadify.swf', 'script': 'uploadify.php', 'folder': 'upload', 'cancelImg': 'cancel.png', 'checkscript' : 'check.php', 'fileDesc' : 'jpg;png;bmp;gif', /*'queueID' : 'fileQueue',*/ // id где будет появляться список 'multi' : false, 'fileExt' : '*.jpg;*.png;*.gif,;*.jpeg', 'onComplete' : function(event,queueID,fileObj,response,data) { $('#response').slideDown('slow'); //$('#response').append(response); $('#response').append('<div><span class="ui-icon ui-icon-closethick"></span><b>' + response+ '</b></div>'); /*-----------------------------уличная магия будет здесь ;)-----------------------------*/ $.ajax({ 'url' : 'ajaxhandler.php', 'type': 'post', 'data': { 'path': response, 'action': 'parsepath' }, 'success': function(data){ //alert(data); $('#cropcontainer').html('<iframe id="pic" height="600" width="100%" />'); // $('#path').val('ff'); $('#pic').attr('src', 'iframe.php' + '?filename=upload/' + data); } }) /*-------------------------------------конец уличной магии =)------------------------------*/ } }); }); |
Алгоритм прост до безумия: после асинхронно загрузки файла на сервер (мы будем загружать по одному файлу), обрабатывается событие onComplete uploadify, которое загружает специально подготовленный iframe, проделывающий всю грязную работу.
Вот собственно он сам.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | <?php /** * этой штукой мы отображаем картинку с возможностью ресайзинга */ $filename = $_GET['filename']; ?> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="js/jquery-1.4.2.min.js"></script> <script src="js/jquery.Jcrop.min.js"></script> <link rel="stylesheet" href="css/jcrop/jquery.Jcrop.css" type="text/css" /> <script type="text/javascript"> $(function(){ $('form').submit(function(){ $.ajax({ 'url' : 'cut.php', 'type': 'post', 'data': { x: $('#x').val(), y: $('#y').val(), w: $('#w').val(), h: $('#h').val(), f: $('#f').val() // filename }, 'success': function(data){ $("#thumbs",top.document).append('<img src="' + data + '" />'); $('#pic', top.document).slideUp('slow'); } }) return false; }) $('#cropbox').Jcrop({ // FIXME: пропорции в отдельный конфиг aspectRatio: 4/3, onSelect: updateCoords }); }); function updateCoords(c) { $('#x').val(c.x); $('#y').val(c.y); $('#w').val(c.w); $('#h').val(c.h); }; function checkCoords() { if (parseInt($('#w').val())) return true; alert('Выделите область для миниатюры'); return false; }; </script> </head> <body> <img src="<?php echo $filename; ?>" id="cropbox" /> <form action="cut.php" method="post" onsubmit="return checkCoords();"> <input type="hidden" id="x" name="x" /> <input type="hidden" id="y" name="y" /> <input type="hidden" id="w" name="w" /> <input type="hidden" id="h" name="h" /> <input type="hidden" id="f" name="f" value="<?php echo $filename; ?>"/> <input type="submit" value="Закончить двигать квадратик" /> </form> </body> </html> |
И файл cut.php, ему помогающий. Здесь следует отметить то, что поддерживаются только файлы jpeg, но не реализовано никакой защиты, дабы не загромождать пример.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?php if ($_SERVER['REQUEST_METHOD'] == 'POST') { // FIXME: вынести настройки в отдельный файл $targW = 400; $targH = round(3 / 4 * $targW); // 3/4 пропорции для миниатюры $jpegQuality = 100; $src = $_POST['f']; $img_r = imagecreatefromjpeg($src); $dst_r = ImageCreateTrueColor($targW, $targH); imagecopyresampled($dst_r, $img_r, 0, 0, $_POST['x'], $_POST['y'], $targW, $targH, $_POST['w'], $_POST['h']); // FIXME: никогда так не делать $filename = dirname(__FILE__) . '/thumbs/' . basename($_POST['f']); imagejpeg($dst_r, $filename, $jpegQuality); echo 'thumbs/' . basename($filename); // exit; } ?> |
Еще нам понадобится небольшой обработчик AJAX запросов, потому что я сразу не придумал как реализовать это в javascript, поэтому сделал это на PHP, если кто подскажет как буду премного благодарен =)
ajaxhandler.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?php $action = $_POST['action']; switch ($action) { case 'parsepath': echo basename(str_replace('<br />', '', $_POST['path'])); break; default: break; } ?> |
Плагины для jQuery:
Что стоит подправить?
- Сделать проверку на загружаемые файлы
- Реализовать очистку мусора, коего скапливается не очень мало
Удачного вам программирования.
а где можно посмотреть пример как все это работает? )
Без защиты как то страшно все это использовать.
сейчас работаю над усовершенствованием, с вами полностью согласен
Без демо не совсем понятно как это должно работать
8 часов я пытался добится описываемого эффекта. 8 часов вглядывался в каждое слово статьи. Но так и не понял что означает «Вот весь javascript на стринице, придется заменить тот, который остался после последней заметки.»
куда вставлять Java код в плагин crop или upload ? Почему к статье нет исходников. Не исходников плагинов, а именно исходников описываемого примера.
Во всяком случае всё что я добился за 8 часов — так это загрузка файла, его вывод на страницу. После — тишина. Никаких действий не происходит. (((
может мое выражение мыслей немного сумбурно, но я стараюсь комментировать не очевидные моменты
после того, как картинка выводится на страницу, появляется возможность изменить размеры миниатюры (если вы все сделали правильно, как изложено в двух заметках) путем drag&drop
Адовый код. Так и не разобрался. В ‘cropcontainer’ ифрэйме картинку не выводит, переписал код так чтобы выводил в ифрэйме, но в новом окне. Добавил функцию превью кропнутого изображения уже без релоада, чуть ниже в ифрейме. Это оказалось проще чем вставлять ифрейм в первый док. Код выложу позже. Сейтчас очень хочу спать.