Read Image Files with File Reader API

With HTML5 we can read an image file from local file-system, and do something with it in the webpage, such as previewing or uploading it.

HTML5 gives us the FileReader API, which lets us take a reference to a local file, and read its contents directly into the web page.

To test if the browser supports the FileReader API, use the following code.
var history_support = typeof FileReader != "undefined";
We can now get a reference to local files selected by the user in a input[type=file] element.

snippet
<p>Pick an image file:</p>
<input type="file" id="file_selector" />
<script>
var file_selector = document.getElementById("file_selector");
file_selector.addEventListener("change", function() {
var files_array = this.files;
// now, you have a reference to the file(s) that the user selected.
// Do something cool with them!
}, false);
</script>

Once you have a reference to a local file, such as an image file, you can read the contents of that file using a FileReader instance.

snippet
function read_image_file(file) {
var reader = new FileReader();
reader.onload = function(e) {
var image_contents = e.target.result;
// now you have the contents of the file!
};
reader.readAsDataURL(file);
}
Now that you have the file contents, in this case, as a data URI (base64-encoding of the file), you can display it in an img element.

The code all put together looks like this.
snippet
<p>Pick an image file:</p>
<input type="file" id="file_selector" />
<script>
var file_selector = document.getElementById("file_selector");
file_selector.addEventListener("change", function() {
var files_array = this.files;
// we only allowed one file to be selected
if (files_array[0].type.match(/image/)) { // it's an image file
read_image_file(files_array[0]);
}
}, false);

function read_image_file(file) {
var reader = new FileReader();
reader.onload = function(e) {
var image_contents = e.target.result;
var img = document.createElement("img");
img.src = image_contents;
document.body.appendChild(img);
};
reader.readAsDataURL(file);
}
</script>
This code snippet assumes only one file being selected, but the <input type="file"> element now supports the "multiple" attribute, which allows the user to select more than one file at a time. This is why we receive an array of file references, rather than a single file reference. If you also want to let the user upload the image file they’ve selected, you simply need to send the file’s contents to the server via an XHR Ajax call.

snippet
<p>Pick an image file:</p>
<input type="file" id="file_selector" />
<input type="button" id="upload" value="Upload Image" disabled />
<script>
var file_selector = document.getElementById("file_selector");
file_selector.addEventListener("change", function() {
var files_array = this.files;

// we only allowed one file to be selected
if (files_array[0].type.match(/image/)) { // it's an image file
read_image_file(files_array[0]);
file_selector.disabled = true; // disable the file selector now
var upload = document.getElementById("upload");
upload.disabled = false;
upload.addEventListener("click", function() {
upload_file(files_array[0]);
}, false);
}
}, false);

function upload_file(file) {
var xhr = new XMLHttpRequest();
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.setRequestHeader("X-File-Name", file.fileName);
xhr.setRequestHeader("X-File-Size", file.fileSize);
xhr.setRequestHeader("X-File-Type", file.type);
xhr.open("GET", "image_upload.php");
xhr.send(file);
}

function read_image_file(file) {
var reader = new FileReader();
reader.onload = function(e) {
var image_contents = e.target.result;
var img = document.createElement("img");
img.src = image_contents;
document.body.appendChild(img);
};
reader.readAsDataURL(file);
}
</script>

Now we have access to the file’s name, size, and type, and so you send that data along to the server along with the file’s contents. Other than that, we’re not doing much extra here that’s particularly HTML5’y—we’re just using standard XHR to upload the file.

The FileReader API provides a readAsBinaryString(...) method, which gives you a binary string representation of the file’s contents. If you know the format
of the file you are reading, you can perform various operations on this data.