Data PNG Base64 ke kanvas HTML5

90

Saya ingin memuat gambar PNG yang dikodekan dalam Base64 ke elemen kanvas. Saya memiliki kode ini:

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

Di Chrome 8 saya mendapatkan kesalahan: Uncaught TypeError: Type error

Dan di Firebug Firefox ini: "Jenis objek tidak kompatibel dengan jenis yang diharapkan dari parameter yang terkait dengan objek" kode: "17"

Dalam base64 itu adalah 5x5px persegi hitam PNG yang telah saya buat di GIMP dan mengubahnya menjadi base64 di program GNU / Linux base64.

Tomáš Nesrovnal
sumber

Jawaban:

172

Dari kelihatannya, Anda harus benar-benar melewatkan drawImage objek gambar seperti itu

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>

Saya sudah mencobanya di chrome dan berfungsi dengan baik.

Jerryf
sumber
8
Jawaban bagus, tetapi apakah Anda yakin ini berhasil setiap saat? Saya merasa kesulitan menggambar gambar segera setelah menyetel src, karena Anda seharusnya menggunakan onloadcallback untuk memastikan gambar selesai dimuat. 50% pengujian saya gagal karena gambar belum selesai dimuat.
Scott Rippey
Wow! Ledakan dari masa lalu :). Anda benar. Jika Anda memanggil drawImage tepat setelah Anda menyetel src dari gambar, Anda mungkin akan mengalami masalah dan tergantung pada situasi Anda, kemungkinan besar Anda ingin menggunakan onload untuk memastikan bahwa gambar tersebut benar-benar dimuat sebelum Anda mencoba merender ke kanvas. Kode di atas hanyalah lebih dari contoh yang menunjukkan bahwa drawImage sebenarnya membutuhkan objek gambar dan cara meneruskannya.
Jerryf
8
Hanya sebagai catatan, jika Anda mengulang sejumlah kanvas, Anda mungkin ingin mengubahnya ctx.drawImage(this,0,0);sehingga memastikan variabel gambar mengacu pada gambar yang benar. Jawaban yang bagus!
Asrama
13
Peristiwa onload harus disetel sebelum src. Terkadang src dapat dimuat secara instan dan tidak pernah mengaktifkan peristiwa onload
Totty.js
3
Tapi, jika data:image/panjangnya besar kita akan mendapatkan414 (Request-URI Too Long
Sarath
17

Jawaban Jerryf baik-baik saja, kecuali satu kekurangan.

Peristiwa onload harus disetel sebelum src. Terkadang src dapat dimuat secara instan dan tidak pernah mengaktifkan peristiwa onload.

(Seperti yang ditunjukkan 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";
John
sumber
2
Btw: Saya mengedit jawaban Jerryf, tetapi seseorang menolaknya. Itu tidak mungkin Jerryf, karena profilnya mengatakan dia terakhir masuk pada tahun 2014.
John
3
"Terkadang src dapat dimuat secara instan dan tidak pernah mengaktifkan peristiwa onload." Saya pikir kejadian ini sangat jarang atau hampir tidak pernah terjadi, tetapi tidak ada alasan untuk tidak membiasakan diri untuk mengatur onloadsebelumnya src... Saya membuat kebiasaan untuk melakukannya.
tandaiE
2
@markE Tidak jarang. Ini akan terjadi sepanjang waktu saat browser menyimpan gambar, misalnya saat browser memuat ulang. Ini terjadi di mesin IE dalam program c ++.
Stefan Rein