Dữ liệu Base64 PNG sang canvas HTML5


89

Tôi muốn tải một hình ảnh PNG được mã hóa trong Base64 vào phần tử canvas. Tôi có mã này:

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

Trong Chrome 8, tôi gặp lỗi: Uncaught TypeError: Type error

Và trong Firebug của Firefox điều này: "Kiểu của một đối tượng không tương thích với kiểu dự kiến ​​của tham số được liên kết với đối tượng" mã: "17"

Trong base64 đó là hình vuông PNG màu đen 5x5px mà tôi đã tạo trong GIMP và chuyển nó thành base64 trong chương trình base64 của GNU / Linux.

Câu trả lời:


170

Nhìn bề ngoài, bạn cần thực sự chuyển drawImage một đối tượng hình ảnh như vậy

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>

Tôi đã thử nó trong chrome và nó hoạt động tốt.


8
Câu trả lời tốt, nhưng bạn có chắc điều này hoạt động mọi lúc? Tôi thấy có lỗi khi vẽ hình ảnh ngay sau khi đặt src, vì bạn phải sử dụng lệnh onloadgọi lại để đảm bảo hình ảnh đã tải xong. 50% thử nghiệm của tôi không thành công vì hình ảnh chưa tải xong.
Scott Rippey

Chà! Vụ nổ từ quá khứ :). Bạn khá chính xác. Nếu bạn đang gọi drawImage ngay sau khi bạn đặt src của hình ảnh, bạn có thể sẽ gặp sự cố và tùy thuộc vào tình huống của bạn, bạn rất có thể sẽ muốn sử dụng onload để đảm bảo rằng hình ảnh thực sự được tải trước khi bạn cố gắng kết xuất nó vào canvas. Đoạn mã trên chỉ là một ví dụ cho thấy rằng drawImage thực sự yêu cầu một đối tượng hình ảnh và cách truyền nó cho nó.
Jerryf

8
Cũng như một lưu ý, nếu bạn đang lặp lại một số canvasses, bạn có thể muốn thay đổi nó để ctx.drawImage(this,0,0);đảm bảo biến hình ảnh tham chiếu đến hình ảnh chính xác. Câu trả lời tuyệt vời mặc dù!
ngủ tập thể

13
Sự kiện onload phải được đặt trước src. Đôi khi src có thể được tải ngay lập tức và không bao giờ kích hoạt sự kiện đang tải
Totty.js Ngày

3
Nhưng, nếu data:image/chiều dài là lớn chúng tôi sẽ nhận được414 (Request-URI Too Long
Sarath

17

Câu trả lời của Jerryf là ổn, ngoại trừ một lỗ hổng.

Sự kiện onload phải được đặt trước src. Đôi khi src có thể được tải ngay lập tức và không bao giờ kích hoạt sự kiện onload.

(Giống như Totty.js đã chỉ ra.)

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
Btw: Tôi đã chỉnh sửa câu trả lời của Jerryf, nhưng ai đó đã từ chối nó. Đó không thể là Jerryf, vì hồ sơ của anh ấy cho biết anh ấy đăng nhập lần cuối vào năm 2014.
John

2
"Đôi khi src có thể được tải ngay lập tức và không bao giờ kích hoạt sự kiện onload." Tôi nghĩ sự xuất hiện của điều này là cực kỳ hiếm đến gần như không bao giờ, nhưng không có lý do gì để không tạo thói quen onloadtrước đó src... Tôi làm cho nó thành một thói quen.
markE

2
@markE Nó không phải là hiếm. Nó sẽ xảy ra mọi lúc khi trình duyệt lưu hình ảnh vào bộ nhớ cache, chẳng hạn như khi tải lại trình duyệt. Điều này đã xảy ra trong một công cụ IE trong một chương trình c ++.
Stefan Rein
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.