• Создание миниатюр на стороне клиента без перезагрузки страницы или немного уличной магии

    by  • 25.08.2010 • javascript, jQuery, php, программирование • Комментарии [7]

    uploadify jcrop1 150x150 Создание миниатюр на стороне клиента без перезагрузки страницы или немного уличной магииСейчас я расскажу вам, как связывал 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:

    Что стоит подправить?

    1. Сделать проверку на загружаемые файлы
    2. Реализовать очистку мусора, коего скапливается не очень мало

    Удачного вам программирования.

    Комментарии к "Создание миниатюр на стороне клиента без перезагрузки страницы или немного уличной магии"

    1. Максим
      10.09.2010 at 19:32

      а где можно посмотреть пример как все это работает? )

    2. 13.09.2010 at 01:54

      Без защиты как то страшно все это использовать.

      • 13.09.2010 at 10:36

        сейчас работаю над усовершенствованием, с вами полностью согласен

    3. tonik
      26.03.2011 at 08:42

      Без демо не совсем понятно как это должно работать

    4. tonik
      27.03.2011 at 14:31

      8 часов я пытался добится описываемого эффекта. 8 часов вглядывался в каждое слово статьи. Но так и не понял что означает «Вот весь javascript на стринице, придется заменить тот, который остался после последней заметки.»
      куда вставлять Java код в плагин crop или upload ? Почему к статье нет исходников. Не исходников плагинов, а именно исходников описываемого примера.

      Во всяком случае всё что я добился за 8 часов — так это загрузка файла, его вывод на страницу. После — тишина. Никаких действий не происходит. (((

      • 27.03.2011 at 18:26

        может мое выражение мыслей немного сумбурно, но я стараюсь комментировать не очевидные моменты

        Во всяком случае всё что я добился за 8 часов – так это загрузка файла, его вывод на страницу. После – тишина. Никаких действий не происходит. (((

        после того, как картинка выводится на страницу, появляется возможность изменить размеры миниатюры (если вы все сделали правильно, как изложено в двух заметках) путем drag&drop

        • tonik
          29.03.2011 at 18:08

          Адовый код. Так и не разобрался. В ‘cropcontainer’ ифрэйме картинку не выводит, переписал код так чтобы выводил в ифрэйме, но в новом окне. Добавил функцию превью кропнутого изображения уже без релоада, чуть ниже в ифрейме. Это оказалось проще чем вставлять ифрейм в первый док. Код выложу позже. Сейтчас очень хочу спать.

    Добавить комментарий

    Ваш e-mail не будет опубликован. Обязательные поля помечены *