By Simbian


2010-12-16 09:51:32 8 Comments

I want to be able to preview a file (image) before it is uploaded. The preview action should be executed all in the browser without using Ajax to upload the image.

How can I do this?

18 comments

@Steve Jiang 2017-03-28 11:28:15

It's my code.Support IE[6-9]、chrome 17+、firefox、Opera 11+、Maxthon3

   
function previewImage(fileObj, imgPreviewId) {
    var allowExtention = ".jpg,.bmp,.gif,.png";  //allowed to upload file type
    document.getElementById("hfAllowPicSuffix").value;
    var extention = fileObj.value.substring(fileObj.value.lastIndexOf(".") + 1).toLowerCase();
    var browserVersion = window.navigator.userAgent.toUpperCase();
    if (allowExtention.indexOf(extention) > -1) {
        if (fileObj.files) {
            if (window.FileReader) {
                var reader = new FileReader();
                reader.onload = function (e) {
                    document.getElementById(imgPreviewId).setAttribute("src", e.target.result);
                };
                reader.readAsDataURL(fileObj.files[0]);
            } else if (browserVersion.indexOf("SAFARI") > -1) {
                alert("don't support  Safari6.0 below broswer");
            }
        } else if (browserVersion.indexOf("MSIE") > -1) {
            if (browserVersion.indexOf("MSIE 6") > -1) {//ie6
                document.getElementById(imgPreviewId).setAttribute("src", fileObj.value);
            } else {//ie[7-9]
                fileObj.select();
                fileObj.blur(); 
                var newPreview = document.getElementById(imgPreviewId);

                newPreview.style.border = "solid 1px #eeeeee";
                newPreview.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='" + document.selection.createRange().text + "')";
                newPreview.style.display = "block";

            }
        } else if (browserVersion.indexOf("FIREFOX") > -1) {//firefox
            var firefoxVersion = parseFloat(browserVersion.toLowerCase().match(/firefox\/([\d.]+)/)[1]);
            if (firefoxVersion < 7) {//firefox7 below
                document.getElementById(imgPreviewId).setAttribute("src", fileObj.files[0].getAsDataURL());
            } else {//firefox7.0+ 
                document.getElementById(imgPreviewId).setAttribute("src", window.URL.createObjectURL(fileObj.files[0]));
            }
        } else {
            document.getElementById(imgPreviewId).setAttribute("src", fileObj.value);
        }
    } else {
        alert("only support" + allowExtention + "suffix");
        fileObj.value = ""; //clear Selected file
        if (browserVersion.indexOf("MSIE") > -1) {
            fileObj.select();
            document.selection.clear();
        }

    }
}
function changeFile(elem) {
    //file object , preview img tag id
    previewImage(elem,'imagePreview')
}
<input type="file"  id="netBarBig"  onchange="changeFile(this)"  />
<img  src="" id="imagePreview" style="width:120px;height:80px;" alt=""/>

@Ivan Baev 2010-12-16 09:55:11

Please take a look at the sample code below:

function readURL(input) {
  if (input.files && input.files[0]) {
    var reader = new FileReader();
    
    reader.onload = function(e) {
      $('#blah').attr('src', e.target.result);
    }
    
    reader.readAsDataURL(input.files[0]);
  }
}

$("#imgInp").change(function() {
  readURL(this);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form runat="server">
  <input type='file' id="imgInp" />
  <img id="blah" src="#" alt="your image" />
</form>

Also, you can try this sample here.

@Jaider 2013-09-03 14:45:02

You can improve a little bit performance by define the reader once. jsfiddle.net/LvsYc/638

@EasyBB 2014-07-21 19:26:12

Why use jQuery for ` $('#blah').attr('src', e.target.result);` when you could have simply done document.getElementById('blah').src=e.target.result)

@Sumi Straessle 2017-03-13 09:07:58

I made a ReactJS implementation of this. Works like a charm. @kxc you should make an ajax call and send input.files[0] as data, see jQuery's doc.

@Liam Appleyard 2018-04-24 10:44:42

Why not use reader.result rather than e.target.result?

@Old Geezer 2018-08-30 02:23:54

@IvanBaev input.files[0] does not have the full path. How does FileReader locate the file?

@RahulAN 2018-10-21 09:02:20

How to do the same with PDF files ?

@TarangP 2018-12-15 09:10:55

what if no file is choosen after upload one ?\

@etlds 2019-05-06 15:52:06

Because he used .chage() anyway? @EasyBB

@EasyBB 2019-05-08 04:39:34

Doesn't matter, whenever you can don't use jquery as it is bloated and vanilla will give you faster results especially if you have tons of scripts.

@Bej 2019-05-28 10:40:24

@EasyBB After changing the orientation of the image, how to replace it with the actual uploaded image? I am getting the old image only.

@D. Petrov 2019-06-07 09:54:07

Just to mention like 9 years later, leaving an empty src attribute to the image will cause your browser to fire additional requests to the page, which may be the unsuspected cause of major issues later on.

@Jinu Joseph Daniel 2017-04-10 19:25:18

function assignFilePreviews() {
    $('input[data-previewable=\"true\"]').change(function() {
        var prvCnt = $(this).attr('data-preview-container');
        if (prvCnt) {
            if (this.files && this.files[0]) {
                var reader = new FileReader();
                reader.onload = function(e) {
                    var img = $('<img>');
                    img.attr('src', e.target.result);
                    img.error(function() {
                        $(prvCnt).html('');
                    });
                    $(prvCnt).html('');
                    img.appendTo(prvCnt);
                }
                reader.readAsDataURL(this.files[0]);
            }
        }
    });
}
$(document).ready(function() {
    assignFilePreviews();
});

HTML

<input type="file" data-previewable="true" data-preview-container=".prd-img-prv" />
<div class = "prd-img-prv"></div>

This also handles case when file with invalid type ( ex. pdf ) is choosen

@cnlevy 2014-11-18 20:00:29

One-liner solution:

The following code uses object URLs, which is much more efficient than data URL for viewing large images (A data URL is a huge string containing all of the file data, whereas an object URL, is just a short string referencing the file data in-memory):

<img id="blah" alt="your image" width="100" height="100" />

<input type="file" 
    onchange="document.getElementById('blah').src = window.URL.createObjectURL(this.files[0])">

Generated URL will be like:

blob:http%3A//localhost/7514bc74-65d4-4cf0-a0df-3de016824345

@Raptor 2015-07-23 06:58:59

version notice: supports by IE10+ caniuse.com/#feat=bloburls

@Kaiido 2017-07-02 02:20:26

@Raptor and so is the whole File API... (FileReader, input.files etc.) URL.createObjectURL is the way to go when dealing with user submitted files, it only creates an in-memory symlink to the real file on user's disk.

@Abhishek Singh 2018-12-26 13:16:25

@cnlevy How can we access the files uploaded? Is it only possible to get it from the URL as you mentioned? To be specific, I'm using flask which already supports access of uploaded files. Is there some other way with this one-liner?

@Nisal Edu 2017-12-21 04:44:51

Try this

window.onload = function() {
  if (window.File && window.FileList && window.FileReader) {
    var filesInput = document.getElementById("uploadImage");
    filesInput.addEventListener("change", function(event) {
      var files = event.target.files;
      var output = document.getElementById("result");
      for (var i = 0; i < files.length; i++) {
        var file = files[i];
        if (!file.type.match('image'))
          continue;
        var picReader = new FileReader();
        picReader.addEventListener("load", function(event) {
          var picFile = event.target;
          var div = document.createElement("div");
          div.innerHTML = "<img class='thumbnail' src='" + picFile.result + "'" +
            "title='" + picFile.name + "'/>";
          output.insertBefore(div, null);
        });        
        picReader.readAsDataURL(file);
      }

    });
  }
}
<input type="file" id="uploadImage" name="termek_file" class="file_input" multiple/>
<div id="result" class="uploadPreview">

@Keyur K 2017-12-16 14:46:40

For Multiple image upload (Modification to the @IvanBaev's Solution)

function readURL(input) {
    if (input.files && input.files[0]) {
        var i;
        for (i = 0; i < input.files.length; ++i) {
          var reader = new FileReader();
          reader.onload = function (e) {
              $('#form1').append('<img src="'+e.target.result+'">');
          }
          reader.readAsDataURL(input.files[i]);
        }
    }
}

http://jsfiddle.net/LvsYc/12330/

Hope this helps someone.

@Sivashanmugam Kannan 2016-11-30 05:57:23

Clean and simple JSfiddle

This will be useful when you want The event to triggered indirectly from a div or a button.

<img id="image-preview"  style="height:100px; width:100px;"  src="" >

<input style="display:none" id="input-image-hidden" onchange="document.getElementById('image-preview').src = window.URL.createObjectURL(this.files[0])" type="file" accept="image/jpeg, image/png">

<button  onclick="HandleBrowseClick('input-image-hidden');" >UPLOAD IMAGE</button>


<script type="text/javascript">
function HandleBrowseClick(hidden_input_image)
{
    var fileinputElement = document.getElementById(hidden_input_image);
    fileinputElement.click();
}     
</script>

@Regular Joe 2017-10-11 20:27:13

Just a note: I can't take credit for this but you can use <label> and avoid javascript for handling the button click altogether. Trigger File-input with pure HTML/CSS., and it's not hacky at all.

@Robert TheSim 2017-08-01 06:07:14

for my app, with encryped GET url parameters, only this worked. I always got a TypeError: $(...) is null. Taken from https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL

function previewFile() {
  var preview = document.querySelector('img');
  var file    = document.querySelector('input[type=file]').files[0];
  var reader  = new FileReader();

  reader.addEventListener("load", function () {
    preview.src = reader.result;
  }, false);

  if (file) {
    reader.readAsDataURL(file);
  }
}
<input type="file" onchange="previewFile()"><br>
<img src="" height="200" alt="Image preview...">

@Ratan Paul 2015-11-26 06:33:53

Example with multiple images using JavaScript (jQuery) and HTML5

JavaScript (jQuery)

function readURL(input) {
     for(var i =0; i< input.files.length; i++){
         if (input.files[i]) {
            var reader = new FileReader();

            reader.onload = function (e) {
               var img = $('<img id="dynamic">');
               img.attr('src', e.target.result);
               img.appendTo('#form1');  
            }
            reader.readAsDataURL(input.files[i]);
           }
        }
    }

    $("#imgUpload").change(function(){
        readURL(this);
    });
}

Markup (HTML)

<form id="form1" runat="server">
    <input type="file" id="imgUpload" multiple/>
</form>

@Nino Škopac 2015-12-14 15:30:49

Here's a multiple files version, based on Ivan Baev's answer.

The HTML

<input type="file" multiple id="gallery-photo-add">
<div class="gallery"></div>

JavaScript / jQuery

$(function() {
    // Multiple images preview in browser
    var imagesPreview = function(input, placeToInsertImagePreview) {

        if (input.files) {
            var filesAmount = input.files.length;

            for (i = 0; i < filesAmount; i++) {
                var reader = new FileReader();

                reader.onload = function(event) {
                    $($.parseHTML('<img>')).attr('src', event.target.result).appendTo(placeToInsertImagePreview);
                }

                reader.readAsDataURL(input.files[i]);
            }
        }

    };

    $('#gallery-photo-add').on('change', function() {
        imagesPreview(this, 'div.gallery');
    });
});

Requires jQuery 1.8 due to the usage of $.parseHTML, which should help with XSS mitigation.

This will work out of the box, and the only dependancy you need is jQuery.

@Muhammad Awais 2016-07-29 18:41:57

Following is the working code.

<input type='file' onchange="readURL(this);" /> 
<img id="ShowImage" src="#" />

Javascript:

 function readURL(input) {
        if (input.files && input.files[0]) {
            var reader = new FileReader();

            reader.onload = function (e) {
                $('#ShowImage')
                    .attr('src', e.target.result)
                    .width(150)
                    .height(200);
            };

            reader.readAsDataURL(input.files[0]);
        }
    }

@Dmitri Dmitri 2011-12-24 11:58:15

The answer of LeassTaTT works well in "standard" browsers like FF and Chrome. The solution for IE exists, but looks different. Here description of cross-browser solution:

In HTML we need two preview elements, img for standard browsers and div for IE

HTML:

<img id="preview" 
     src="" 
     alt="" 
     style="display:none; max-width: 160px; max-height: 120px; border: none;"/>

<div id="preview_ie"></div>

In CSS we specify the following IE specific thing:

CSS:

#preview_ie {
  FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale)
}  

In HTML we include the standard and the IE-specific Javascripts:

<script type="text/javascript">
  {% include "pic_preview.js" %}
</script>  
<!--[if gte IE 7]> 
<script type="text/javascript">
  {% include "pic_preview_ie.js" %}
</script>

The pic_preview.js is the Javascript from the LeassTaTT's answer. Replace the $('#blah') whith the $('#preview') and add the $('#preview').show()

Now the IE specific Javascript (pic_preview_ie.js):

function readURL (imgFile) {    
  var newPreview = document.getElementById('preview_ie');
  newPreview.filters.item('DXImageTransform.Microsoft.AlphaImageLoader').src = imgFile.value;
  newPreview.style.width = '160px';
  newPreview.style.height = '120px';
}    

That's is. Works in IE7, IE8, FF and Chrome. Please test in IE9 and report. The idea of IE preview was found here: http://forums.asp.net/t/1320559.aspx

http://msdn.microsoft.com/en-us/library/ms532969(v=vs.85).aspx

@Andrew 2015-07-27 06:01:14

I have made a plugin which can generate the preview effect in IE 7+ thanks to the internet, but has few limitations. I put it into a github page so that its easier to get it

$(function () {
		$("input[name=file1]").previewimage({
			div: ".preview",
			imgwidth: 180,
			imgheight: 120
		});
		$("input[name=file2]").previewimage({
			div: ".preview2",
			imgwidth: 90,
			imgheight: 90
		});
	});
.preview > div {
  display: inline-block;
  text-align:center;
}

.preview2 > div {
  display: inline-block; 
  text-align:center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://rawgit.com/andrewng330/PreviewImage/master/preview.image.min.js"></script>
	Preview
	<div class="preview"></div>
	Preview2
	<div class="preview2"></div>

	<form action="#" method="POST" enctype="multipart/form-data">
		<input type="file" name="file1">
		<input type="file" name="file2">
		<input type="submit">
	</form>

@nkron 2014-11-27 08:17:06

There are a couple ways you can do this. The most efficient way would be to use URL.createObjectURL() on the File from your <input>. Pass this URL to img.src to tell the browser to load the provided image.

Here's an example:

<input type="file" accept="image/*" onchange="loadFile(event)">
<img id="output"/>
<script>
  var loadFile = function(event) {
    var output = document.getElementById('output');
    output.src = URL.createObjectURL(event.target.files[0]);
  };
</script>

You can also use FileReader.readAsDataURL() to parse the file from your <input>. This will create a string in memory containing a base64 representation of the image.

<input type="file" accept="image/*" onchange="loadFile(event)">
<img id="output"/>
<script>
  var loadFile = function(event) {
    var reader = new FileReader();
    reader.onload = function(){
      var output = document.getElementById('output');
      output.src = reader.result;
    };
    reader.readAsDataURL(event.target.files[0]);
  };
</script>

@tfmontague 2015-01-13 12:02:43

Read carefully: readAsDataURL and createObjectURL will cache an image in the browser, then return a base64 encoded string which references the image location in cache. If browser cache is cleared, the base64 encoded string will no longer reference the image. The base64 string isn't actual image data, it's a url reference to the image, and you shouldn't save it to a database hoping to retrieve image data. I've recently made this mistake (about 3 minutes ago).

@Apolo 2018-11-20 16:09:28

to avoid memory issues you should call URL.revokeObjectURL when you are done with your blob

@Rodolpho Brock 2015-01-06 16:19:57

What about this solution?

Just add the data attribute "data-type=editable" to an image tag like this:

<img data-type="editable" id="companyLogo" src="http://www.coventrywebgraphicdesign.co.uk/wp-content/uploads/logo-here.jpg" height="300px" width="300px" />

And the script to your project off course...

function init() {
    $("img[data-type=editable]").each(function (i, e) {
        var _inputFile = $('<input/>')
            .attr('type', 'file')
            .attr('hidden', 'hidden')
            .attr('onchange', 'readImage()')
            .attr('data-image-placeholder', e.id);

        $(e.parentElement).append(_inputFile);

        $(e).on("click", _inputFile, triggerClick);
    });
}

function triggerClick(e) {
    e.data.click();
}

Element.prototype.readImage = function () {
    var _inputFile = this;
    if (_inputFile && _inputFile.files && _inputFile.files[0]) {
        var _fileReader = new FileReader();
        _fileReader.onload = function (e) {
            var _imagePlaceholder = _inputFile.attributes.getNamedItem("data-image-placeholder").value;
            var _img = $("#" + _imagePlaceholder);
            _img.attr("src", e.target.result);
        };
        _fileReader.readAsDataURL(_inputFile.files[0]);
    }
};

// 
// IIFE - Immediately Invoked Function Expression
// https://stackoverflow.com/questions/18307078/jquery-best-practises-in-case-of-document-ready
(

function (yourcode) {
    "use strict";
    // The global jQuery object is passed as a parameter
    yourcode(window.jQuery, window, document);
}(

function ($, window, document) {
    "use strict";
    // The $ is now locally scoped 
    $(function () {
        // The DOM is ready!
        init();
    });

    // The rest of your code goes here!
}));

See demo at JSFiddle

@Md. Rahman 2014-07-25 11:20:46

Yes. It is possible.

Html

<input type="file" accept="image/*"  onchange="showMyImage(this)" />
 <br/>
<img id="thumbnil" style="width:20%; margin-top:10px;"  src="" alt="image"/>

JS

 function showMyImage(fileInput) {
        var files = fileInput.files;
        for (var i = 0; i < files.length; i++) {           
            var file = files[i];
            var imageType = /image.*/;     
            if (!file.type.match(imageType)) {
                continue;
            }           
            var img=document.getElementById("thumbnil");            
            img.file = file;    
            var reader = new FileReader();
            reader.onload = (function(aImg) { 
                return function(e) { 
                    aImg.src = e.target.result; 
                }; 
            })(img);
            reader.readAsDataURL(file);
        }    
    }

You can get Live Demo from here.

@Sachin Prasad 2014-06-05 06:23:19

I have edited @Ivan's answer to display "No Preview Available" image, if it is not an image:

function readURL(input) {
    var url = input.value;
    var ext = url.substring(url.lastIndexOf('.') + 1).toLowerCase();
    if (input.files && input.files[0]&& (ext == "gif" || ext == "png" || ext == "jpeg" || ext == "jpg")) {
        var reader = new FileReader();

        reader.onload = function (e) {
            $('.imagepreview').attr('src', e.target.result);
        }

        reader.readAsDataURL(input.files[0]);
    }else{
         $('.imagepreview').attr('src', '/assets/no_preview.png');
    }
}

@ajorquera 2014-03-21 13:16:13

How about creating a function that loads the file and fires a custom event. Then attach a listener to the input. This way we have more flexibility to use the file, not just for previewing images.

/**
 * @param {domElement} input - The input element
 * @param {string} typeData - The type of data to be return in the event object. 
 */
function loadFileFromInput(input,typeData) {
    var reader,
        fileLoadedEvent,
        files = input.files;

    if (files && files[0]) {
        reader = new FileReader();

        reader.onload = function (e) {
            fileLoadedEvent = new CustomEvent('fileLoaded',{
                detail:{
                    data:reader.result,
                    file:files[0]  
                },
                bubbles:true,
                cancelable:true
            });
            input.dispatchEvent(fileLoadedEvent);
        }
        switch(typeData) {
            case 'arraybuffer':
                reader.readAsArrayBuffer(files[0]);
                break;
            case 'dataurl':
                reader.readAsDataURL(files[0]);
                break;
            case 'binarystring':
                reader.readAsBinaryString(files[0]);
                break;
            case 'text':
                reader.readAsText(files[0]);
                break;
        }
    }
}
function fileHandler (e) {
    var data = e.detail.data,
        fileInfo = e.detail.file;

    img.src = data;
}
var input = document.getElementById('inputId'),
    img = document.getElementById('imgId');

input.onchange = function (e) {
    loadFileFromInput(e.target,'dataurl');
};

input.addEventListener('fileLoaded',fileHandler)

Probably my code isn't as good as some users but I think you will get the point of it. Here you can see an example

Related Questions

Sponsored Content

52 Answered Questions

[SOLVED] Create GUID / UUID in JavaScript?

  • 2008-09-19 20:01:00
  • Jason Cohen
  • 1538421 View
  • 3738 Score
  • 52 Answer
  • Tags:   javascript guid uuid

33 Answered Questions

[SOLVED] How can I upload files asynchronously?

74 Answered Questions

[SOLVED] What is the JavaScript version of sleep()?

  • 2009-06-04 14:41:10
  • fmsf
  • 2245240 View
  • 1937 Score
  • 74 Answer
  • Tags:   javascript sleep

17 Answered Questions

[SOLVED] Get the size of the screen, current web page and browser window

36 Answered Questions

[SOLVED] How do I loop through or enumerate a JavaScript object?

40 Answered Questions

[SOLVED] How do I format a Microsoft JSON date?

34 Answered Questions

13 Answered Questions

23 Answered Questions

[SOLVED] Event binding on dynamically created elements?

33 Answered Questions

[SOLVED] $(document).ready equivalent without jQuery

  • 2009-04-28 21:51:11
  • FlySwat
  • 942343 View
  • 1849 Score
  • 33 Answer
  • Tags:   javascript jquery

Sponsored Content