It’s an interesting feature. In some cases it’s better when users can preview image before uploading it, e.g. when you want to let users trim the image or process it in any way. As you’ll see it’s pretty easy to do. After reading this article you will know how to add this feature to your web app using Javascript.

Step by step guide to creating preview image

We’ll start off with a simple HTML page with a form and and input element which accepts only image files. Notice that we have an img element with empty src attribute, which we’ll use to display selected image.

1
2
3
4
5
6
7
8
<html>
    <body>
        <img id="preview" src="" />
        <form>
            <input type="file" accept="image/*" />
        </form>
    </body>
</html>

Firstly, we’ll update the preview after user picks image. We will do that by handling onchange event which is triggered once user selects the image. In order to do that we create a new <script> section with an empty function. Later on we’ll implement it to create preview. Notice that we’re passing element as a parameter, which in this case should be our input element.

1
2
3
4
5
<script>
function showPreview (element) {

}
</script>

Then we hook it up with onchange event. Note that we’re passing input element as a parameter using this:

1
<input type="file" accept="image/*" onchange="showPreview(this)" />

The next step it so retrieve selected file using the files array which can be accessed from the element. To make it simple I’ve assumed that there is only one file.

1
2
3
4
5
6
<script>
function showPreview (element) {
    // verification skipped
    var file = element.files[0];
}
</script>

To read the file we’ll use <a href="https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL">FileReader.readAsDataURL</a>, which will convert image into data url.

Data urls allows to embedd files inline in elements, typically using base64 encoding. For example you could display black 1px by 1px image using this code (generated using Png Pixel):

1
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=" />

Then we will use the result (base64 encoded data url image) as an preview image. In this case we have to wait until readAsDataURL is done to get the result, which happens inside load event listener.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<script>
function showPreview (element) {
    var file = element.files[0];
    var preview = document.getElementById("preview");
    var fr = new FileReader();

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

    if (file) {
        fr.readAsDataURL(file);
    }
}
</script>

This will display the image, in full size, so you may want to consider styling it and constraining width and height :)