Dati PNG Base64 su tela HTML5


90

Voglio caricare un'immagine PNG codificata in Base64 nell'elemento canvas. Ho questo codice:

<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 ottengo l'errore: Uncaught TypeError: Type error

E nel Firebug di Firefox questo: "Il tipo di un oggetto non è compatibile con il tipo previsto del parametro associato all'oggetto" codice: "17"

In quel base64 c'è un quadrato PNG nero di 5x5px che ho creato in GIMP e lo trasformo in base64 nel programma base64 di GNU / Linux.

Risposte:


172

A quanto pare devi effettivamente passare a drawImage un oggetto immagine in questo modo

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>

L'ho provato in Chrome e funziona bene.


8
Buona risposta, ma sei sicuro che funzioni ogni volta? Ho trovato bug per disegnare un'immagine subito dopo aver impostato src, perché dovresti usare la onloadrichiamata per assicurarti che l'immagine abbia terminato il caricamento. Il 50% dei miei test non è riuscito perché l'immagine non era stata caricata.
Scott Rippey

Wow! Un tuffo nel passato :). Hai ragione. Se stai chiamando drawImage subito dopo aver impostato src dell'immagine probabilmente incorrerai in problemi ea seconda della tua situazione molto probabilmente vorrai usare onload per assicurarti che l'immagine sia effettivamente caricata prima di tentare di renderizzare sulla tela. Il codice sopra era solo più di un esempio che mostra che drawImage richiede effettivamente un oggetto immagine e come passarglielo.
Jerryf

8
Come nota, se stai eseguendo il loop su un numero di tele, potresti volerlo cambiare in ctx.drawImage(this,0,0);modo che assicuri che la variabile immagine si riferisca all'immagine corretta. Ottima risposta però!
Dormouse

13
L'evento onload dovrebbe essere impostato prima di src. A volte l'src può essere caricato istantaneamente e non attivare mai l'evento onload
Totty.js

3
Ma, se la data:image/lunghezza è grande, otterremo414 (Request-URI Too Long
Sarath

17

La risposta di Jerryf va bene, tranne che per un difetto.

L'evento onload dovrebbe essere impostato prima di src. A volte src può essere caricato istantaneamente e non attivare mai l'evento onload.

(Come ha sottolineato Totty.js.)

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";

2
A proposito: ho modificato la risposta di Jerryf, ma qualcuno l'ha rifiutata. Non può essere stato Jerryf, poiché il suo profilo dice che è stato effettuato l'ultimo accesso nel 2014.
John,

3
"A volte src può essere caricato istantaneamente e non attivare mai l'evento onload." Penso che il verificarsi di ciò sia estremamente raro o quasi mai, ma non c'è motivo per non prendere l'abitudine di stabilire onloadprima src... Io lo prendo.
markE

2
@markE Non è raro. Accadrà tutte le volte che il browser memorizza l'immagine nella cache, ad esempio al ricaricamento del browser. Questo è successo in un motore IE in un programma c ++.
Stefan Rein
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.