ChatGPT解决这个技术问题 Extra ChatGPT

Base64 PNG data to HTML5 canvas

I want to load a PNG image encoded in Base64 to canvas element. I have this code:

<html>
<head>
</head>
<body>
<canvas id="c"></canvas>
<script type="text/javascript">

var canvas = document.getElementById("c");
var ctx = canvas.getContext("2d");

data =  "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oMCRUiMrIBQVkAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAADElEQVQI12NgoC4AAABQAAEiE+h1AAAAAElFTkSuQmCC";

ctx.drawImage(data, 0, 0);

</script>
</body>
</html>

In Chrome 8 I get the error: Uncaught TypeError: Type error

And in Firefox's Firebug this: "The type of an object is incompatible with the expected type of the parameter associated to the object" code: "17"

In that base64 is 5x5px black PNG square that I have made in GIMP and turn it to base64 in GNU/Linux's program base64.


R
Ruslan López

By the looks of it you need to actually pass drawImage an image object like so

var canvas = document.getElementById("c"); var ctx = canvas.getContext("2d"); var image = new Image(); image.onload = function() { ctx.drawImage(image, 0, 0); }; image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oMCRUiMrIBQVkAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAADElEQVQI12NgoC4AAABQAAEiE+h1AAAAAElFTkSuQmCC";

I've tried it in chrome and it works fine.


Good answer, but are you sure this works every time? I found it buggy to draw an image immediately after setting the src, because you're supposed to use the onload callback to ensure the image has finished loading. 50% of my tests failed because the image hadn't finished loading.
Wow! Blast from the past :). You’re quite correct. If you’re calling drawImage just after you’ve set the src of the image you probably will run into problems and depending on your situation you will most likely want to use onload to make sure that the image is actually loaded before you attempt to render it to the canvas. The above code was just more of an example showing that drawImage actually requires an image object and how to pass that to it.
Just as a note, if you're looping over a number of canvasses, you may want to change it to ctx.drawImage(this,0,0); so that it ensures the image variable refers to the correct image. Great answer though!
The onload event should be set before the src. Sometimes the src can be loaded instantly and never fire the onload event
But, if the data:image/ length is large we will get 414 (Request-URI Too Long
J
John

Jerryf's answer is fine, except for one flaw.

The onload event should be set before the src. Sometimes the src can be loaded instantly and never fire the onload event.

(Like Totty.js pointed out.)

var canvas = document.getElementById("c");
var ctx = canvas.getContext("2d");

var image = new Image();
image.onload = function() {
    ctx.drawImage(image, 0, 0);
};
image.src = "data:image/  png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oMCRUiMrIBQVkAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAADElEQVQI12NgoC4AAABQAAEiE+h1AAAAAElFTkSuQmCC";

"Sometimes the src can be loaded instantly and never fire the onload event." I think the occurence of this is extremely rare to almost never, but there's no reason not to make it a habit to set onload before src...I make it a habit to do so.
@markE It is not rare. It will happen all the time when the browser caches the image, for example on a browser reload. This happened in an IE engine in a c++ program.