Données PNG Base64 vers toile HTML5

89

Je souhaite charger une image PNG encodée en Base64 dans un élément canvas. J'ai ce 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>

Dans Chrome 8, j'obtiens l'erreur: Uncaught TypeError: Type error

Et dans Firebug de Firefox ceci: "Le type d'un objet est incompatible avec le type attendu du paramètre associé à l'objet" code: "17"

Dans cette base64 se trouve un carré PNG noir de 5x5px que j'ai créé dans GIMP et le transforme en base64 dans le programme base64 de GNU / Linux.

Tomáš Nesrovnal
la source

Réponses:

171

En apparence, vous devez réellement passer à drawImage un objet image comme celui-ci

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";
<canvas id="c"></canvas>

Je l'ai essayé en chrome et cela fonctionne très bien.

Jerryf
la source
8
Bonne réponse, mais êtes-vous sûr que cela fonctionne à chaque fois? J'ai trouvé bogué de dessiner une image immédiatement après avoir défini le src, car vous êtes censé utiliser le onloadrappel pour vous assurer que le chargement de l'image est terminé. 50% de mes tests ont échoué car l'image n'a pas fini de se charger.
Scott Rippey
Hou la la! Blast from the past :). Vous avez tout à fait raison. Si vous appelez drawImage juste après avoir défini le src de l'image, vous rencontrerez probablement des problèmes et en fonction de votre situation, vous voudrez probablement utiliser onload pour vous assurer que l'image est réellement chargée avant d'essayer de rendre à la toile. Le code ci-dessus était juste plus un exemple montrant que drawImage nécessite en fait un objet image et comment le lui transmettre.
Jerryf
8
À titre indicatif, si vous effectuez une boucle sur un certain nombre de toiles, vous voudrez peut-être le changer pour ctx.drawImage(this,0,0);qu'il s'assure que la variable d'image se réfère à l'image correcte. Excellente réponse cependant!
Loir du
13
L'événement onload doit être défini avant le src. Parfois, le src peut être chargé instantanément et ne jamais déclencher l'événement onload
Totty.js
3
Mais, si la data:image/longueur est grande, nous obtiendrons414 (Request-URI Too Long
Sarath
17

La réponse de Jerryf est bonne, à l'exception d'un défaut.

L'événement onload doit être défini avant le src. Parfois, le src peut être chargé instantanément et ne jamais déclencher l'événement onload.

(Comme Totty.js l'a souligné.)

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";
John
la source
2
Btw: J'ai édité la réponse de Jerryf, mais quelqu'un l'a rejetée. Cela ne peut pas être Jerryf, car son profil indique qu'il a été connecté pour la dernière fois en 2014.
John
2
"Parfois, le src peut être chargé instantanément et ne jamais déclencher l'événement onload." Je pense que cela est extrêmement rare ou presque jamais, mais il n'y a aucune raison de ne pas en faire une habitude à prendre onloadavant src... Je prends l'habitude de le faire.
markE
2
@markE Ce n'est pas rare. Cela se produira tout le temps lorsque le navigateur met en cache l'image, par exemple lors d'un rechargement du navigateur. Cela s'est produit dans un moteur IE dans un programme c ++.
Stefan Rein