Show Thumbnail of Image Upload AJAX/PHP

ajax-image-upload

Update 18/11/2012: The new version of this upload is now here JQUERY AJAX IMAGE UPLOAD THUMBNAIL EXAMPLE.

This is how you can add a file/image upload tool to your forms and have AJAX store the file with PHP and return a thumbnailed version to the user for display on the form. Nice.

How it works

  1. User selects a file/image from the form input field
  2. jQuery sends an AJAX request with the file/image
  3. PHP creates a thumbnail version and sends back the url in JSON format
  4. jQuery displays the thumbnailed version on the form

Download

Download Source FilesSee Live Demo

The jQuery Code – jquery.js

/*******************************************************************
  JS - PREVIEW IMAGE
*******************************************************************/

function previewImage(str) {
    //alert(str);
    ajaxFileUpload();
}

function removeImage() {
    //alert("Image Removed");
    $("#imagethumb").html('');
    $("#removebutton").hide();
    $("#supportedfiles").show();
    var tid = $("Input[name=allocatedimagename]").val();
    //remove the temporary image files created by the image
    $.get("/php/deleteblogthumb.php",{thumb_name: tid, type: 'js-blog'}, function(data){
        //alert(data);
    });

    $("Input[name=allocatedimagename]").val('');
    $("Input[name=blogpic]").val('');
}

function ajaxFileUpload() {
    //starting setting some animation when the ajax starts and completes
    $("#loading")
    .ajaxStart(function(){
        $(this).show();
    })
    .ajaxComplete(function(){
        $(this).hide();
    });
   
    /*
        prepareing ajax file upload
        url: the url of script file handling the uploaded files
                    fileElementId: the file type of input element id and it will be the index of  $_FILES Array()
        dataType: it support json, xml
        secureuri:use secure protocol
        success: call back function when the ajax complete
        error: callback function when the ajax failed
       
            */

    $.ajaxFileUpload
    (
        {
            url:'doajaxfileupload.php',
            secureuri:false,
            fileElementId:'blogpic',
            dataType: 'json',
            success: function (data, status)
            {
                if(typeof(data.error) != 'undefined')
                {
                    if(data.error != '')
                    {
                        alert(data.error);
                    }else
                    {
                        //alert(data.loc);
                        //show the preview of image
                        var imageloc = '<span class="normaltext">Your uploaded image: <samp>'+data.name+'('+data.size+'kb)'+'</samp><br><img class="small blogthumb" src="'+data.loc+'" height="40" width="40" alt="your uploaded image"></span>';
                        $("#imagethumb").html(imageloc); //add
                        $("#removebutton").show();
                        $("#supportedfiles").hide();
                        //save the allocated image name for use with the process signup script
                        $("Input[name=allocatedimagename]").val(data.loc);
                    }
                }
            },
            error: function (data, status, e)
            {
                alert(e);
            }
        }
    )
   
    return false;

}

The jQuery Code – ajaxfileupload.js

jQuery.extend({

    createUploadIframe: function(id, uri)
    {
            //create frame
            var frameId = 'jUploadFrame' + id;
           
            if(window.ActiveXObject) {
                var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />');
                if(typeof uri== 'boolean'){
                    io.src = 'javascript:false';
                }
                else if(typeof uri== 'string'){
                    io.src = uri;
                }
            }
            else {
                var io = document.createElement('iframe');
                io.id = frameId;
                io.name = frameId;
            }
            io.style.position = 'absolute';
            io.style.top = '-1000px';
            io.style.left = '-1000px';

            document.body.appendChild(io);

            return io          
    },
    createUploadForm: function(id, fileElementId)
    {
        //create form  
        var formId = 'jUploadForm' + id;
        var fileId = 'jUploadFile' + id;
        var form = $('<form  action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
        var oldElement = $('#' + fileElementId);
        var newElement = $(oldElement).clone();
        $(oldElement).attr('id', fileId);
        $(oldElement).before(newElement);
        $(oldElement).appendTo(form);
        //set attributes
        $(form).css('position', 'absolute');
        $(form).css('top', '-1200px');
        $(form).css('left', '-1200px');
        $(form).appendTo('body');      
        return form;
    },

    ajaxFileUpload: function(s) {
        // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout       
        s = jQuery.extend({}, jQuery.ajaxSettings, s);
        var id = new Date().getTime()        
        var form = jQuery.createUploadForm(id, s.fileElementId);
        var io = jQuery.createUploadIframe(id, s.secureuri);
        var frameId = 'jUploadFrame' + id;
        var formId = 'jUploadForm' + id;       
        // Watch for a new set of requests
        if ( s.global &amp;&amp; ! jQuery.active++ )
        {
            jQuery.event.trigger( "ajaxStart" );
        }            
        var requestDone = false;
        // Create the request object
        var xml = {}  
        if ( s.global )
            jQuery.event.trigger("ajaxSend", [xml, s]);
        // Wait for a response to come back
        var uploadCallback = function(isTimeout)
        {          
            var io = document.getElementById(frameId);
            try
            {              
                if(io.contentWindow)
                {
                     xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
                     xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
                     
                }else if(io.contentDocument)
                {
                     xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;
                    xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;
                }                      
            }catch(e)
            {
                jQuery.handleError(s, xml, null, e);
            }
            if ( xml || isTimeout == "timeout")
            {              
                requestDone = true;
                var status;
                try {
                    status = isTimeout != "timeout" ? "success" : "error";
                    // Make sure that the request was successful or notmodified
                    if ( status != "error" )
                    {
                        // process the data (runs the xml through httpData regardless of callback)
                        var data = jQuery.uploadHttpData( xml, s.dataType );    
                        // If a local callback was specified, fire it and pass it the data
                        if ( s.success )
                            s.success( data, status );
   
                        // Fire the global callback
                        if( s.global )
                            jQuery.event.trigger( "ajaxSuccess", [xml, s] );
                    } else
                        jQuery.handleError(s, xml, status);
                } catch(e)
                {
                    status = "error";
                    jQuery.handleError(s, xml, status, e);
                }

                // The request was completed
                if( s.global )
                    jQuery.event.trigger( "ajaxComplete", [xml, s] );

                // Handle the global AJAX counter
                if ( s.global &amp;&amp; ! --jQuery.active )
                    jQuery.event.trigger( "ajaxStop" );

                // Process result
                if ( s.complete )
                    s.complete(xml, status);

                jQuery(io).unbind()

                setTimeout(function()
                                    {   try
                                        {
                                            $(io).remove();
                                            $(form).remove();  
                                           
                                        } catch(e)
                                        {
                                            jQuery.handleError(s, xml, null, e);
                                        }                                  

                                    }, 100)

                xml = null

            }
        }
        // Timeout checker
        if ( s.timeout > 0 )
        {
            setTimeout(function(){
                // Check to see if the request is still happening
                if( !requestDone ) uploadCallback( "timeout" );
            }, s.timeout);
        }
        try
        {
           // var io = $('#' + frameId);
            var form = $('#' + formId);
            $(form).attr('action', s.url);
            $(form).attr('method', 'POST');
            $(form).attr('target', frameId);
            if(form.encoding)
            {
                form.encoding = 'multipart/form-data';             
            }
            else
            {              
                form.enctype = 'multipart/form-data';
            }          
            $(form).submit();

        } catch(e)
        {          
            jQuery.handleError(s, xml, null, e);
        }
        if(window.attachEvent){
            document.getElementById(frameId).attachEvent('onload', uploadCallback);
        }
        else{
            document.getElementById(frameId).addEventListener('load', uploadCallback, false);
        }      
        return {abort: function () {}};

    },

    uploadHttpData: function( r, type ) {
        var data = !type;
        data = type == "xml" || data ? r.responseXML : r.responseText;
        // If the type is "script", eval it in global context
        if ( type == "script" )
            jQuery.globalEval( data );
        // Get the JavaScript object, if JSON is used.
        if ( type == "json" )
            eval( "data = " + data );
        // evaluate scripts within html
        if ( type == "html" )
            jQuery("<div>").html(data).evalScripts();
            //alert($('param', data).each(function(){alert($(this).attr('value'));}));
        return data;
    }
})

The PHP Code – doajaxfileupload.php

$ratio2)    {
          $thumb_w=$new_w;
          $thumb_h=$old_y/$ratio1;
        }
        else    {
          $thumb_h=$new_h;
          $thumb_w=$old_x/$ratio2;
        }

          // we create a new image with the new dimmensions
        $dst_img=ImageCreateTrueColor($thumb_w,$thumb_h);

        // resize the big image to the new created one
        imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y);

        // output the created image to the file. Now we will have the thumbnail into the file named by $filename
        if(!strcmp("png",$ext))
          imagepng($dst_img,$filename);
        else
          imagejpeg($dst_img,$filename);

          //destroys source and destination images.
        imagedestroy($dst_img);
        imagedestroy($src_img);
       }

       // This function reads the extension of the file.
       // It is used to determine if the file is an image by checking the extension.
       function getExtension($str) {
               $i = strrpos($str,".");
               if (!$i) { return ""; }
               $l = strlen($str) - $i;
               $ext = substr($str,$i+1,$l);
               return $ext;
       }

        //reads the name of the file the user submitted for uploading
       $image=$_FILES[$fileElementName]['name'];

    // if it is not empty
    if ($image)
    {
        // get the original name of the file from the clients machine
        $filename = stripslashes($_FILES[$fileElementName]['name']);

        // get the extension of the file in a lower case format
        $extension = getExtension($filename);
        $extension = strtolower($extension);
        // if it is not a known extension, we will suppose it is an error, print an error message
        //and will not upload the file, otherwise we continue
        if (($extension != "jpg")  &amp;&amp; ($extension != "jpeg") &amp;&amp; ($extension != "png"))
        {
            $error .= 'Unknown extension!';
            $errors=1;
        }
        else
        {
            // get the size of the image in bytes
            // $_FILES[\'image\'][\'tmp_name\'] is the temporary filename of the file in which
            //the uploaded file was stored on the server
            $size=getimagesize($_FILES[$fileElementName]['tmp_name']);
            $sizekb=filesize($_FILES[$fileElementName]['tmp_name']);

            //compare the size with the maxim size we defined and print error if bigger
            if ($sizekb > MAX_SIZE*1024)
            {
                $error .= 'You have exceeded the size limit!';
                $errors=1;
            }
            else {

              //we will give an unique name, for example the time in unix time format
            $image_name=time().'.'.$extension;
            //the new name will be containing the full path where will be stored (images folder)
            $newname="/images/masters/".$image_name;
            $copied = copy($_FILES[$fileElementName]['tmp_name'], $newname);
            //we verify if the image has been uploaded, and print error instead
            if (!$copied)
            {
              $error .= 'Copy unsuccessfull!';
              $errors=1;
            }
            else
            {
              // the new thumbnail image will be placed in images/thumbs/ folder
              $thumb_name='/images/thumbs/thumb_'.$image_name;
              // call the function that will create the thumbnail. The function will get as parameters
              //the image name, the thumbnail name and the width and height desired for the thumbnail
              $thumb=make_thumb($newname,$thumb_name,40,40);

              //also add the users pic
              $thumb_name='/images/thumbs/thumb_'.$image_name;
              $thumb=make_thumb($newname,$thumb_name,110,110);

            }}
        }
            }

      //--------- END SECOND SCRIPT --------------------------------------------------------------------

      //return variables to javascript
            $filename = $_FILES[$fileElementName]['name'];
            $filesize = round(($sizekb/1000), 0);
            $fileloc = $thumb_name;
            //for security reason, we force to remove all uploaded file
            @unlink($_FILES[$fileElementName]);
    }
    $return_JSON = "";
    $return_JSON .= "{";
    $return_JSON .=             "error: '" . $error . "',\n";
    $return_JSON .=             "name: '" . $filename . "',\n";
    $return_JSON .=             "size: '" . $filesize . "',\n";
    $return_JSON .=             "loc: '" . $fileloc . "'\n";
    $return_JSON .= "}";
    echo $return_JSON;
?>

The HTML Code

          <label for="blogpic">Blog Thumbnail Picture:</label>
          <input type="file" size="23" id="blogpic" name="blogpic" onChange="javascript:previewImage(this.value)"/>
          <div id="preview-image">
              <div id="imagethumb"></div>
              <input type="text" id="allocatedimagename" name="allocatedimagename" />
              <div id="loading" style="visibility:hidden"><img src="/images/loading.gif" alt="loading" title="loading" /></div>
              <div id="supportedfiles"><p class="nomargin">Supported file types: jpg, jpeg, png (max 1mb) <br/>Your image will be resized to 110 by 110 px (40 by 40 for blog thumbs)</p></div>

              <div id="removebutton"><button id="buttonremove" onclick="javascript:removeImage()">Remove</button></div>
          </div>