37

I'm trying to use drawImage to draw a semi-transparent PNG on a canvas element. However, it draws the image as completely opaque. When I look at the resource that's being loaded and load the actual PNG in the browser, it shows the transparency, but when I draw it on the canvas, it does not. Any ideas?

Here's the code:

drawing = new Image() 
drawing.src = "draw.png" 
context.drawImage(drawing,0,0);
pixielex
  • 779
  • 2
  • 8
  • 13
  • 1
    Please show a reproducible test case with the problem, and the OS/browser/version where it is failing. This generally works correctly. – Phrogz Jan 23 '12 at 19:53
  • I had the same problem and my html looks like this [one](http://www.w3schools.com/html/tryit.asp?filename=tryhtml5_canvas_tut_img). Does it matter where the script is placed? When you press submit it works but when you reload the page the picture is not rendered – kon psych May 26 '13 at 23:24

5 Answers5

39

Don't forget to add an event listener to the image's load event. Image loading is something that happens in the background, so when the JavaScript interpreter gets to the canvas.drawImage part it is most likely the image probably will not have loaded yet and is just an empty image object, without content.

drawing = new Image();
drawing.src = "draw.png"; // can also be a remote URL e.g. http://
drawing.onload = function() {
   context.drawImage(drawing,0,0);
};
funie200
  • 3,688
  • 5
  • 21
  • 34
Menno Bieringa
  • 1,215
  • 12
  • 17
11

You can simply insert any transparent image using Image object:

var canvas=document.getElementById("canvas");
var context=canvas.getContext('2d');
var image=new Image();
image.onload=function(){
context.drawImage(image,0,0,canvas.width,canvas.height);
};
image.src="http://www.lunapic.com/editor/premade/transparent.gif";
<canvas id="canvas" width="500" height="500">your canvas loads here</canvas>
  • 1
    Same as the one with most upvotes. The difference between the question and these 2 answers is the `image.onload`. –  Feb 23 '21 at 23:39
4

If you are drawing it in a render loop, you need to make sure to run context.clearRect( 0, 0, width, height ) first, otherwise you are just writing the png over the png every frame, which will eventually be opaque. (But frames render fast, so you wouldn't see this with the naked eye.)

enb081
  • 3,831
  • 11
  • 43
  • 66
Stev0
  • 59
  • 4
4

It ought to work fine, are you sure your image is really transparent and not just white in the background?

Here's an example of drawing a transparent PNG over a black rectangle to base your code off of:

http://jsfiddle.net/5P2Ms/

Simon Sarris
  • 62,212
  • 13
  • 141
  • 171
3

NB, if you was to use canvas.toDataURL and you set the mimetype to anything other than say gif or png, the transparent parts of the image will be completely black.

drawing = new Image();
drawing.onload = function () {
    context.drawImage(drawing,0,0);
    var base64 = canvas.toDataURL('image/png', 1);
};
drawing.src = "draw.png";
Luke Madhanga
  • 6,871
  • 2
  • 43
  • 47