Base64-PNG-Daten in HTML5-Zeichenfläche

86

Ich möchte ein in Base64 codiertes PNG-Bild in das Canvas-Element laden. Ich habe diesen 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 erhalte ich folgende Fehlermeldung: Uncaught TypeError: Type error

Und in Firefoxs Firebug: "Der Typ eines Objekts ist nicht kompatibel mit dem erwarteten Typ des Parameters, der dem Objekt zugeordnet ist." Code: "17"

In diesem base64 befindet sich ein 5x5px schwarzes PNG-Quadrat, das ich in GIMP erstellt habe, und wandle es in base64 im GNU / Linux-Programm base64 um.

Tomáš Nesrovnal
quelle

Antworten:

167

Wie es aussieht, müssen Sie drawImage tatsächlich an ein Bildobjekt wie dieses übergeben

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>

Ich habe es in Chrom versucht und es funktioniert gut.

Jerryf
quelle
8
Gute Antwort, aber sind Sie sicher, dass dies jedes Mal funktioniert? Ich fand es fehlerhaft, ein Bild sofort nach dem Einstellen von zu zeichnen src, da Sie den onloadRückruf verwenden sollten, um sicherzustellen, dass das Bild vollständig geladen wurde. 50% meiner Tests sind fehlgeschlagen, weil das Bild noch nicht vollständig geladen wurde.
Scott Rippey
Beeindruckend! Explosion aus der Vergangenheit :). Du bist ganz richtig. Wenn Sie drawImage aufrufen, nachdem Sie den Quellcode des Bildes festgelegt haben, treten wahrscheinlich Probleme auf. Abhängig von Ihrer Situation möchten Sie höchstwahrscheinlich Onload verwenden, um sicherzustellen, dass das Bild tatsächlich geladen wird, bevor Sie versuchen, es zu rendern es auf die Leinwand. Der obige Code war nur ein Beispiel dafür, dass drawImage tatsächlich ein Bildobjekt benötigt und wie man es an dieses weitergibt.
Jerryf
8
Wenn Sie eine Reihe von Leinwänden durchlaufen, möchten Sie diese möglicherweise so ändern, ctx.drawImage(this,0,0);dass sichergestellt ist, dass die Bildvariable auf das richtige Bild verweist. Tolle Antwort!
Siebenschläfer
13
Das Onload-Ereignis sollte vor dem src gesetzt werden. Manchmal kann der src sofort geladen werden und löst niemals das Onload-Ereignis aus
Totty.js
3
Aber wenn die data:image/Länge groß ist, werden wir bekommen414 (Request-URI Too Long
Sarath
17

Jerryfs Antwort ist bis auf einen Fehler in Ordnung.

Das Onload-Ereignis sollte vor dem src gesetzt werden. Manchmal kann der src sofort geladen werden und das Onload-Ereignis niemals auslösen.

(Wie Totty.js betonte.)

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
quelle
2
Übrigens: Ich habe Jerryfs Antwort bearbeitet, aber jemand hat sie abgelehnt. Es kann nicht Jerryf gewesen sein, wie sein Profil sagt, dass er zuletzt im Jahr 2014 angemeldet wurde.
John
2
"Manchmal kann der src sofort geladen werden und das Onload-Ereignis niemals auslösen." Ich denke, das Auftreten ist äußerst selten bis fast nie, aber es gibt keinen Grund, es sich nicht zur Gewohnheit zu machen, onloadvorher zu setzen src... Ich mache es mir zur Gewohnheit, dies zu tun.
Markieren Sie den
2
@markE Es ist nicht selten. Dies geschieht immer dann, wenn der Browser das Bild zwischenspeichert, z. B. beim erneuten Laden des Browsers. Dies geschah in einer IE-Engine in einem C ++ - Programm.
Stefan Rein