HTML5 Image uploader with Jcrop

HTML5 Image uploader with Jcrop


Step 1. HTML

Our first step is html markup. first, we have to put styles and scripts in the HEAD section:
1<!-- add styles -->
2<link href="css/main.css" rel="stylesheet" type="text/css" />
3<link href="css/jquery.Jcrop.min.css" rel="stylesheet" type="text/css" />
4
5<!-- add scripts -->
6<script src="js/jquery.min.js"></script>
7<script src="js/jquery.Jcrop.min.js"></script>
8<script src="js/script.js"></script>
And now, in the BODY section we can put our form:
01<div class="bbody">
02
03    <!-- upload form -->
04    <form id="upload_form" enctype="multipart/form-data" method="post" action="upload.php" onsubmit="return checkForm()">
05        <!-- hidden crop params -->
06        <input type="hidden" id="x1" name="x1" />
07        <input type="hidden" id="y1" name="y1" />
08        <input type="hidden" id="x2" name="x2" />
09        <input type="hidden" id="y2" name="y2" />
10
11        <h2>Step1: Please select image file</h2>
12        <div><input type="file" name="image_file" id="image_file" onchange="fileSelectHandler()" /></div>
13
14        <div class="error"></div>
15
16        <div class="step2">
17            <h2>Step2: Please select a crop region</h2>
18            <img id="preview" />
19
20            <div class="info">
21                <label>File size</label> <input type="text" id="filesize" name="filesize" />
22                <label>Type</label> <input type="text" id="filetype" name="filetype" />
23                <label>Image dimension</label> <input type="text" id="filedim" name="filedim" />
24                <label>W</label> <input type="text" id="w" name="w" />
25                <label>H</label> <input type="text" id="h" name="h" />
26            </div>
27
28            <input type="submit" value="Upload" />
29        </div>
30    </form>
31</div>
I hope that all is clear at this step – this is usual upload form, with hidden and visible fields, once we have selected an image, we will see second step (crop). Once we have cropped necessary area, we can Upload our result.

Step 2. CSS

Now, I would like to give you CSS styles to stylize our form:

css/main.css

01.bheader {
02    background-color: #DDDDDD;
03    border-radius: 10px 10px 0 0;
04    padding: 10px 0;
05    text-align: center;
06}
07.bbody {
08    color: #000;
09    overflow: hidden;
10    padding-bottom: 20px;
11    text-align: center;
12
13    background: -moz-linear-gradient(#ffffff, #f2f2f2);
14    background: -ms-linear-gradient(#ffffff, #f2f2f2);
15    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100%, #f2f2f2));
16    background: -webkit-linear-gradient(#ffffff, #f2f2f2);
17    background: -o-linear-gradient(#ffffff, #f2f2f2);
18    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f2f2f2');
19    -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f2f2f2')";
20    background: linear-gradient(#ffffff, #f2f2f2);
21}
22.bbody h2, .info, .error {
23    margin: 10px 0;
24}
25.step2, .error {
26    display: none;
27}
28.error {
29    font-size: 18px;
30    font-weight: bold;
31    color: red;
32}
33.info {
34    font-size: 14px;
35}
36label {
37    margin: 0 5px;
38}
39input {
40    border: 1px solid #CCCCCC;
41    border-radius: 10px;
42    padding: 4px 8px;
43    text-align: center;
44    width: 70px;
45}
46.jcrop-holder {
47    display: inline-block;
48}
49input[type=submit] {
50    background: #e3e3e3;
51    border: 1px solid #bbb;
52    border-radius: 3px;
53    -webkit-box-shadow: inset 0 0 1px 1px #f6f6f6;
54    box-shadow: inset 0 0 1px 1px #f6f6f6;
55    color: #333;
56    font: bold 12px/1 "helvetica neue", helvetica, arial, sans-serif;
57    padding: 8px 0 9px;
58    text-align: center;
59    text-shadow: 0 1px 0 #fff;
60    width: 150px;
61}
62input[type=submit]:hover {
63    background: #d9d9d9;
64    -webkit-box-shadow: inset 0 0 1px 1px #eaeaea;
65    box-shadow: inset 0 0 1px 1px #eaeaea;
66    color: #222;
67    cursor: pointer;
68}
69input[type=submit]:active {
70    background: #d0d0d0;
71    -webkit-box-shadow: inset 0 0 1px 1px #e3e3e3;
72    box-shadow: inset 0 0 1px 1px #e3e3e3;
73    color: #000;
74}

Step 3. JS

Our next step – is javascript. Please review the result code (my comments are below the code):

001// convert bytes into friendly format

002function bytesToSize(bytes) {
003    var sizes = ['Bytes', 'KB', 'MB'];
004    if (bytes == 0) return 'n/a';
005    var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
006    return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
007};
008
009// check for selected crop region
010function checkForm() {
011    if (parseInt($('#w').val())) return true;
012    $('.error').html('Please select a crop region and then press Upload').show();
013    return false;
014};
015
016// update info by cropping (onChange and onSelect events handler)
017function updateInfo(e) {
018    $('#x1').val(e.x);
019    $('#y1').val(e.y);
020    $('#x2').val(e.x2);
021    $('#y2').val(e.y2);
022    $('#w').val(e.w);
023    $('#h').val(e.h);
024};
025
026// clear info by cropping (onRelease event handler)
027function clearInfo() {
028    $('.info #w').val('');
029    $('.info #h').val('');
030};
031
032function fileSelectHandler() {
033
034    // get selected file
035    var oFile = $('#image_file')[0].files[0];
036
037    // hide all errors
038    $('.error').hide();
039
040    // check for image type (jpg and png are allowed)
041    var rFilter = /^(image\/jpeg|image\/png)$/i;
042    if (! rFilter.test(oFile.type)) {
043        $('.error').html('Please select a valid image file (jpg and png are allowed)').show();
044        return;
045    }
046
047    // check for file size
048    if (oFile.size > 250 * 1024) {
049        $('.error').html('You have selected too big file, please select a one smaller image file').show();
050        return;
051    }
052
053    // preview element
054    var oImage = document.getElementById('preview');
055
056    // prepare HTML5 FileReader
057    var oReader = new FileReader();
058        oReader.onload = function(e) {
059
060        // e.target.result contains the DataURL which we can use as a source of the image
061        oImage.src = e.target.result;
062        oImage.onload = function () { // onload event handler
063
064            // display step 2
065            $('.step2').fadeIn(500);
066
067            // display some basic image info
068            var sResultFileSize = bytesToSize(oFile.size);
069            $('#filesize').val(sResultFileSize);
070            $('#filetype').val(oFile.type);
071            $('#filedim').val(oImage.naturalWidth + ' x ' + oImage.naturalHeight);
072
073            // Create variables (in this scope) to hold the Jcrop API and image size
074            var jcrop_api, boundx, boundy;
075
076            // destroy Jcrop if it is existed
077            if (typeof jcrop_api != 'undefined')
078                jcrop_api.destroy();
079
080            // initialize Jcrop
081            $('#preview').Jcrop({
082                minSize: [32, 32], // min crop size
083                aspectRatio : 1, // keep aspect ratio 1:1
084                bgFade: true, // use fade effect
085                bgOpacity: .3, // fade opacity
086                onChange: updateInfo,
087                onSelect: updateInfo,
088                onRelease: clearInfo
089            }, function(){
090
091                // use the Jcrop API to get the real image size
092                var bounds = this.getBounds();
093                boundx = bounds[0];
094                boundy = bounds[1];
095
096                // Store the Jcrop API in the jcrop_api variable
097                jcrop_api = this;
098            });
099        };
100    };
101
102    // read selected file as DataURL
103    oReader.readAsDataURL(oFile);
104}
There are several common functions in the beginning: bytesToSize, checkForm, updateInfo and clearInfo. They are pretty easy. The next function (fileSelectHandler) is more complex, basically, this is the main function. When we have selected a file (I suppose – image file), we will check this file for Type and Size. You can see here a filter for image formats: png and jpg. Plus, we don’t need very large images, I think that 250kb is more than enough. Then, if everything is ok, we can read our selected file using FileReader::readAsDataURL (html5 function). And, once it has loaded, we can continue: we should display step2 with Preview and info section, and then – we have to initialize (or – reinitialize) Jcrop for our Preview image. This is how it works. Once we have cropped the image, we can click ‘Upload’ button in order to send result to the server.

Step 4. PHP

In this step – we have to accept (and upload) our result photo. I prepared next useful PHP function for you:

upload.php

01function uploadImageFile() { // Note: GD library is required for this function
02
03    if ($_SERVER['REQUEST_METHOD'] == 'POST') {
04        $iWidth = $iHeight = 200; // desired image result dimensions
05        $iJpgQuality = 90;
06
07        if ($_FILES) {
08
09            // if no errors and size less than 250kb
10            if (! $_FILES['image_file']['error'] && $_FILES['image_file']['size'] < 250 * 1024) {
11                if (is_uploaded_file($_FILES['image_file']['tmp_name'])) {
12
13                    // new unique filename
14                    $sTempFileName = 'cache/' . md5(time().rand());
15
16                    // move uploaded file into cache folder
17                    move_uploaded_file($_FILES['image_file']['tmp_name'], $sTempFileName);
18
19                    // change file permission to 644
20                    @chmod($sTempFileName, 0644);
21
22                    if (file_exists($sTempFileName) && filesize($sTempFileName) > 0) {
23                        $aSize = getimagesize($sTempFileName); // try to obtain image info
24                        if (!$aSize) {
25                            @unlink($sTempFileName);
26                            return;
27                        }
28
29                        // check for image type
30                        switch($aSize[2]) {
31                            case IMAGETYPE_JPEG:
32                                $sExt = '.jpg';
33
34                                // create a new image from file
35                                $vImg = @imagecreatefromjpeg($sTempFileName);
36                                break;
37                            case IMAGETYPE_PNG:
38                                $sExt = '.png';
39
40                                // create a new image from file
41                                $vImg = @imagecreatefrompng($sTempFileName);
42                                break;
43                            default:
44                                @unlink($sTempFileName);
45                                return;
46                        }
47
48                        // create a new true color image
49                        $vDstImg = @imagecreatetruecolor( $iWidth, $iHeight );
50
51                        // copy and resize part of an image with resampling
52                        imagecopyresampled($vDstImg, $vImg, 0, 0, (int)$_POST['x1'], (int)$_POST['y1'], $iWidth, $iHeight, (int)$_POST['w'], (int)$_POST['h']);
53
54                        // define a result image filename
55                        $sResultFileName = $sTempFileName . $sExt;
56
57                        // output image to file
58                        imagejpeg($vDstImg, $sResultFileName, $iJpgQuality);
59                        @unlink($sTempFileName);
60
61                        return $sResultFileName;
62                    }
63                }
64            }
65        }
66    }
67}
68
69$sImage = uploadImageFile();
70echo '<img src="'.$sImage.'" />';
For more details visit: http://www.script-tutorials.com/html5-image-uploader-with-jcrop/

Comments

  1. ImagerJs is a platform-independent, web-based JavaScript
    Image Uploader that is very easy and fun to use. A JavaScript library
    for uploading images using drag & drop. Crop, rotate, resize,
    or shrink your image before uploading https://www.imagerjs.com visit us you wont
    be sorry! Have a nice day.

    ReplyDelete

Post a Comment