8
votes

I'm trying to get the Base64/Data URL of a chosen image file in Javascript. The user basically selects an image via the File Input control and the Data URL is generated. However, I get this error:

Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap)'

HTML:

<body>
    <form id="form1">
    <div>
        <input type="file" id="imageinput" onchange="testit(event)" />
        <canvas width="300" height="300" id="mycanvas" style="display: none;"></canvas>
    </div>
    </form>
</body>

Javascript:

function testit(event) {

            var myImage = URL.createObjectURL(event.target.files[0]);

            var myCanvas = document.getElementById('mycanvas');

            var ctx = myCanvas.getContext('2d');

            ctx.drawImage(myImage, 0, 0);

            var mydataURL = myCanvas.toDataURL('image/jpg');

            alert(mydataURL);

        }

Why isn't this code working, guys?

2
you need to put that url on an img tag's src and then pass the img to the canvas to draw, once loaded.dandavis

2 Answers

8
votes

You can not draw an image from url directly to canvas. You have to create a image element/object to do that.

var myCanvas = document.getElementById('mycanvas');
var ctx = myCanvas.getContext('2d');
var img = new Image();
img.onload = function(){
    ctx.drawImage(img, 0, 0);

    alert(myCanvas.toDataURL('image/jpeg'));
};

img.src = URL.createObjectURL(event.target.files[0]);

Here we have created a image object and set the src to user selected image url. After the image is loaded we are adding it to the canvas.

EDIT:

Here we have one more problem. Whatever the image size is, you will always get 300x300 cropped dataurl of the image because of the static canvas width and height. So we can set the width and height to the canvas dynamically after the image loaded. We can use console.log() instead of alert() so that you can open and see the image from your console in your browser itself.

myCanvas.width = img.width;
myCanvas.height = img.height;

Here is the final code:

var myCanvas = document.getElementById('mycanvas');
var ctx = myCanvas.getContext('2d');
var img = new Image();
img.onload = function(){
    myCanvas.width = img.width;
    myCanvas.height = img.height;

    ctx.drawImage(img, 0, 0);

    console.log(myCanvas.toDataURL('image/jpeg'));
};

img.src = URL.createObjectURL(event.target.files[0]);

Here is the fiddle (i have made the canvas visible so that you can see the whole image and width and height change in canvas):

UPDATE:

As @Kaiido mentioned, It will produce PNG image since the 'image/jpg' is not the mimetype. 'image/jpeg' is the mimetype for both JPG and JPEG images.

Updated Fiddle:

http://jsfiddle.net/k7moorthi/r8soo95p/4/

6
votes

You're trying to draw an object URL to the canvas. you need to create an image in memory first

http://jsfiddle.net/zmtu6t6c/4/

var myImageUrl = URL.createObjectURL(event.target.files[0]);
var myImage = new Image();
myImage.src = myImageUrl;

myImage.onload = function(){

... then do the canvas stuff

}