Categories
file-upload javascript jquery

Preview an image before it is uploaded

1989

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?

2

3108

imgInp.onchange = evt => {
  const [file] = imgInp.files
  if (file) {
    blah.src = URL.createObjectURL(file)
  }
}
<form runat="server">
  <input accept="image/*" type="file" id="imgInp" />
  <img id="blah" src="#" alt="your image" />
</form>

4

  • 13

    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.

    Mar 13, 2017 at 9:07


  • 1

    what if no file is choosen after upload one ?\

    – TarangP

    Dec 15, 2018 at 9:10

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

    – Bej

    May 28, 2019 at 10:40


  • Internet Explorer version 20H2 says evt => is a wrong syntax :(.

    – Esamo

    Jul 27, 2021 at 11:54

487

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]);
    output.onload = function() {
      URL.revokeObjectURL(output.src) // free memory
    }
  };
</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>

5

  • 14

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

    – Apolo

    Nov 20, 2018 at 16:09


  • 6

    @Apolo not in this case, see this answer: stackoverflow.com/a/49346614/2313004

    – grreeenn

    Apr 17, 2020 at 22:52

  • about your first comment @tfmontague. Are you sure? I just copied the bese64 string after using readAsDataURL and opened it in another browser and it works.

    Oct 8, 2020 at 15:17

  • @Lonel Lupu – Believe my answer was incorrect! Also used readAsDataURL and was able to convert the base64 characters into an image.

    Oct 29, 2020 at 11:05

  • 2

    Read carefully: When an image is uploaded using the file input, it is stored in the browser’s cache. The URL.createObjectURL() will create a link to the cached image on the browser. To create the base64 string of the file which can be stored in a database use readAsDataURL.

    Oct 29, 2020 at 11:33


291

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

6

  • 2

    @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.

    – Kaiido

    Jul 2, 2017 at 2:20

  • @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?

    Dec 26, 2018 at 13:16


  • 1

    This solution not worked for me. Image preview not showing.

    Nov 29, 2019 at 7:35

  • 1

    Beautiful. But what about clearing memory using URL.revokeObjectURL()? 😀

    – pheianox

    Mar 27, 2021 at 7:10

  • 1

    @pheianox It depends on you, because it is not that big of a problem. “Browsers will release object URLs automatically when the document is unloaded; however, for optimal performance and memory usage, if there are safe times when you can explicitly unload them, you should do so”. For more info MDN reference

    – Rajan

    Apr 1, 2021 at 13:12