Adatum
Фев
14
2013

HTML5 Загрузка и обрезка изображений

crop
Многих волнует вопрос как загрузить фотографии на сайт, и я решил приоткрыть завесу тайны, но думаю, что просто загрузка файлов слишком просто, поэтому я решил добавить нужную функцию — обрезка изображения. Мы будем использовать HTML5 FileReader для выполнения обрезки с Jcrop (JQuery библиотеки).

Демо Скачать

Это позволит избавиться от ненужных шагов и в результате — мы получим 3-ступенчатый процесс. Выбор Файла -> Обрезка -> Загрузка. во время выбора файла, мы будем проверять тип и размер файла (для того, чтобы избежать громадных файлов). Давайте приступим.

Шаг 1. HTML

Наш первый шаг это разметка HTML:

          
        <link href="css/jquery.Jcrop.min.css" rel="stylesheet" type="text/css" />
        <script src="js/jquery.min.js"></script>
        <script src="js/jquery.Jcrop.min.js"></script>
        <script src="js/script.js"></script>
 
<div class="container">		
                <form id="upload_form" enctype="multipart/form-data" method="post" action="upload.php" onsubmit="return checkForm()">
                    <!-- hidden crop params -->
                    <input type="hidden" id="x1" name="x1" />
                    <input type="hidden" id="y1" name="y1" />
                    <input type="hidden" id="x2" name="x2" />
                    <input type="hidden" id="y2" name="y2" />

                    <h2>Шаг 1: Пожалуйста, выберите файл изображения</h2>
                    <div><input type="file" name="image_file" id="image_file" onchange="fileSelectHandler()" /></div>

                    <div class="error"></div>

                    <div class="step2">
                        <h2>Шаг 2: Пожалуйста, выберите область</h2>
                        <img id="preview" />
                         <br><br>
                        <div class="info">
                            <label>Размер файла: </label> <input type="text" id="filesize" name="filesize" />
                            <label>Тип: </label> <input type="text" id="filetype" name="filetype" />
                            <label>Размер изображения</label> <input type="text" id="filedim" name="filedim" /><br><br>
                            <label>W</label> <input type="text" id="w" name="w" /><br><br>
                            <label>H</label> <input type="text" id="h" name="h" /><br><br>
                        </div>

                        <input type="submit" class="button default" value="Обрезать и загрузить" />
                    </div>
                </form>
            
        </div>
    </body>
</html>

Шаг 2. JS

Следующий шаг javascript.

js/script.js

// convert bytes into friendly format
function bytesToSize(bytes) {
    var sizes = ['Bytes', 'KB', 'MB'];
    if (bytes == 0) return 'n/a';
    var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
    return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
};

// check for selected crop region
function checkForm() {
    if (parseInt($('#w').val())) return true;
    $('.error').html('Please select a crop region and then press Upload').show();
    return false;
};

// update info by cropping (onChange and onSelect events handler)
function updateInfo(e) {
    $('#x1').val(e.x);
    $('#y1').val(e.y);
    $('#x2').val(e.x2);
    $('#y2').val(e.y2);
    $('#w').val(e.w);
    $('#h').val(e.h);
};

// clear info by cropping (onRelease event handler)
function clearInfo() {
    $('.info #w').val('');
    $('.info #h').val('');
};

function fileSelectHandler() {

    // get selected file
    var oFile = $('#image_file')[0].files[0];

    // hide all errors
    $('.error').hide();

    // check for image type (jpg and png are allowed)
    var rFilter = /^(image\/jpeg|image\/png)$/i;
    if (! rFilter.test(oFile.type)) {
        $('.error').html('Please select a valid image file (jpg and png are allowed)').show();
        return;
    }

    // check for file size
    if (oFile.size > 250 * 1024) {
        $('.error').html('You have selected too big file, please select a one smaller image file').show();
        return;
    }

    // preview element
    var oImage = document.getElementById('preview');

    // prepare HTML5 FileReader
    var oReader = new FileReader();
        oReader.onload = function(e) {

        // e.target.result contains the DataURL which we can use as a source of the image
        oImage.src = e.target.result;
        oImage.onload = function () { // onload event handler

            // display step 2
            $('.step2').fadeIn(500);

            // display some basic image info
            var sResultFileSize = bytesToSize(oFile.size);
            $('#filesize').val(sResultFileSize);
            $('#filetype').val(oFile.type);
            $('#filedim').val(oImage.naturalWidth + ' x ' + oImage.naturalHeight);

            // Create variables (in this scope) to hold the Jcrop API and image size
            var jcrop_api, boundx, boundy;

            // destroy Jcrop if it is existed
            if (typeof jcrop_api != 'undefined')
                jcrop_api.destroy();

            // initialize Jcrop
            $('#preview').Jcrop({
                minSize: [32, 32], // min crop size
                aspectRatio : 1, // keep aspect ratio 1:1
                bgFade: true, // use fade effect
                bgOpacity: .3, // fade opacity
                onChange: updateInfo,
                onSelect: updateInfo,
                onRelease: clearInfo
            }, function(){

                // use the Jcrop API to get the real image size
                var bounds = this.getBounds();
                boundx = bounds[0];
                boundy = bounds[1];

                // Store the Jcrop API in the jcrop_api variable
                jcrop_api = this;
            });
        };
    };

    // read selected file as DataURL
    oReader.readAsDataURL(oFile);
}

Здесь несколько общих функций: bytesToSize, checkForm, UpdateInfo и clearInfo.

Шаг 3. PHP

Теперь мы должны загрузить наш результат фото.
Осуществляется это вот этим php скриптом.
upload.php

function uploadImageFile() { // Note: GD library is required for this function

    if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        $iWidth = $iHeight = 200; // desired image result dimensions
        $iJpgQuality = 90;

        if ($_FILES) {

            // if no errors and size less than 250kb
            if (! $_FILES['image_file']['error'] && $_FILES['image_file']['size'] < 250 * 1024) {
                if (is_uploaded_file($_FILES['image_file']['tmp_name'])) {

                    // new unique filename
                    $sTempFileName = 'cache/' . md5(time().rand());

                    // move uploaded file into cache folder
                    move_uploaded_file($_FILES['image_file']['tmp_name'], $sTempFileName);

                    // change file permission to 644
                    @chmod($sTempFileName, 0644);

                    if (file_exists($sTempFileName) && filesize($sTempFileName) > 0) {
                        $aSize = getimagesize($sTempFileName); // try to obtain image info
                        if (!$aSize) {
                            @unlink($sTempFileName);
                            return;
                        }

                        // check for image type
                        switch($aSize[2]) {
                            case IMAGETYPE_JPEG:
                                $sExt = '.jpg';

                                // create a new image from file
                                $vImg = @imagecreatefromjpeg($sTempFileName);
                                break;
                            case IMAGETYPE_PNG:
                                $sExt = '.png';

                                // create a new image from file
                                $vImg = @imagecreatefrompng($sTempFileName);
                                break;
                            default:
                                @unlink($sTempFileName);
                                return;
                        }

                        // create a new true color image
                        $vDstImg = @imagecreatetruecolor( $iWidth, $iHeight );

                        // copy and resize part of an image with resampling
                        imagecopyresampled($vDstImg, $vImg, 0, 0, (int)$_POST['x1'], (int)$_POST['y1'], $iWidth, $iHeight, (int)$_POST['w'], (int)$_POST['h']);

                        // define a result image filename
                        $sResultFileName = $sTempFileName . $sExt;

                        // output image to file
                        imagejpeg($vDstImg, $sResultFileName, $iJpgQuality);
                        @unlink($sTempFileName);

                        return $sResultFileName;
                    }
                }
            }
        }
    }
}

$sImage = uploadImageFile();
echo '<img src="'.$sImage.'" />';

Мы должны проверить размер и формат файла на стороне сервера. Мы получим двойную защиту (на стороне пользователя и на стороне сервера) от ненужных файлов. После того как мы загрузили изображение (с помощью функции move_uploaded_file) — мы можем обрезать его (с помощью функций imagecreatefromjpeg, imagecreatetruecolor и imagecopyresampled), а также — включить результат в файл изображения с помощью функции imagejpeg. В результате мы получим небольшое изображение (200px × 200px), так что, кроме обрезки, мы меняем размер изображения, и наконец — мы можем увидеть наше изображение на экране. Вот и все.

Источник урока: http://www.script-tutorials.com/html5-image-uploader-with-jcrop/
Перевел: Сергоманов Дмитрий

Похожие статьи

Оставить комментарий

*

  • мой email vitalikr44@yandex.ru

  • а как сделать так, чтобы выделение было не квадратным, а чтобы сохранялись пропорции размера 230х350

  • Огромное спасибо! Было бы ещё интереснее если бы вы могли добавить вот эти две функции.

    1) размер выбранной области не может быть меньше 200px на 200px и больше 200px на 500px.
    2) Из выбранной области сделать ещё миниатюры 100 на 100 и 50 на 50

    Спасибо и за это!

    p.s как в вк.

    мой сайт на котором хочу сделать это. http://sprashivay.hol.es