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 > |
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 > |
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 h 2 , .info, .error { |
23 | margin : 10px 0 ; |
24 | } |
25 | .step 2 , .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 | } |
36 | label { |
37 | margin : 0 5px ; |
38 | } |
39 | input { |
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 | } |
49 | input[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 | } |
62 | input[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 | } |
69 | input[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 |
002 | function 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 |
010 | function 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) |
017 | function 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) |
027 | function clearInfo() { |
028 | $( '.info #w' ).val( '' ); |
029 | $( '.info #h' ).val( '' ); |
030 | }; |
031 |
032 | function 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 | } |
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
01 | function 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(); |
70 | echo '<img src="' . $sImage . '" />' ; |
For more details visit: http://www.script-tutorials.com/html5-image-uploader-with-jcrop/
ImagerJs is a platform-independent, web-based JavaScript
ReplyDeleteImage 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.