How can I draw an image from the HTML5 File API on Canvas? How can I draw an image from the HTML5 File API on Canvas? javascript javascript

How can I draw an image from the HTML5 File API on Canvas?


You have a File instance which is not an image.

To get an image, use new Image(). The src needs to be an URL referencing to the selected File. You can use URL.createObjectURL to get an URL referencing to a Blob (a File is also a Blob): http://jsfiddle.net/t7mv6/86/.

var ctx = document.getElementById('canvas').getContext('2d');var img = new Image;img.onload = function() {    ctx.drawImage(img, 20,20);    alert('the image is drawn');}img.src = URL.createObjectURL(e.target.files[0]);

Note: be sure to revoke the object url when you are done with it otherwise you'll leak memory. If you're not doing anything too crazy, you can just stick a URL.revokeObjectURL(img.src) in the img.onload function.

References:


Live Example

function handleFiles(e) {    var ctx = document.getElementById('canvas').getContext('2d');    var url = URL.createObjectURL(e.target.files[0]);    var img = new Image();    img.onload = function() {        ctx.drawImage(img, 20, 20);        }    img.src = url;   }

window.URL.createObjectUrldocs

You could also use the FileReader instead to create the object URL.

The FileReader has slightly better browser support.

The FileReader approach works in FF6 / Chrome. I'm not certain whether setting Img.src to a Blob is valid and cross-browser though.

Creating object urls is the correct way to do it.

Edit:

As mentioned in the commment window.URL support whilst offline seems unavailable in FF6/Chrome.


Here is a complete example (Fiddle) using FileReader (which has better browser support as mentioned by Raynos). In this example I also scale Canvas to fit the image.

In real life example you might scale the image to some maximum so that your form will not blow up ;-). Here is an example with scaling (Fiddle).

var URL = window.webkitURL || window.URL;window.onload = function() {    var input = document.getElementById('input');    input.addEventListener('change', handleFiles, false);        // set original canvas dimensions as max    var canvas = document.getElementById('canvas');    canvas.dataMaxWidth = canvas.width;    canvas.dataMaxHeight = canvas.height;}function handleFiles(e) {    var ctx = document.getElementById('canvas').getContext('2d');    var reader  = new FileReader();    var file = e.target.files[0];    // load to image to get it's width/height    var img = new Image();    img.onload = function() {        // setup scaled dimensions        var scaled = getScaledDim(img, ctx.canvas.dataMaxWidth, ctx.canvas.dataMaxHeight);        // scale canvas to image        ctx.canvas.width = scaled.width;        ctx.canvas.height = scaled.height;        // draw image        ctx.drawImage(img, 0, 0            , ctx.canvas.width, ctx.canvas.height        );    }    // this is to setup loading the image    reader.onloadend = function () {        img.src = reader.result;    }    // this is to read the file    reader.readAsDataURL(file);}// returns scaled dimensions objectfunction getScaledDim(img, maxWidth, maxHeight) {    var scaled = {        ratio: img.width / img.height,        width: img.width,        height: img.height    }    if (scaled.width > maxWidth) {        scaled.width = maxWidth;        scaled.height = scaled.width / scaled.ratio;    }    if (scaled.height > maxHeight) {        scaled.height = maxHeight;        scaled.width = scaled.height / scaled.ratio;    }    return scaled;}
canvas {    border:1px solid black}
<input type="file" id="input"/><div>    <canvas width="400" height="300" id="canvas"/></div>