Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

html5-canvas: Conversion of Image file to DataURL throws Uncaught TypeError

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?

like image 615
Dinuka Jay Avatar asked Oct 08 '15 19:10

Dinuka Jay


2 Answers

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

}
like image 182
dave.mcalpine Avatar answered Oct 23 '22 23:10

dave.mcalpine


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/

like image 36
Kesavamoorthi Avatar answered Oct 23 '22 21:10

Kesavamoorthi