Данные PNG Base64 в холст HTML5


89

Я хочу загрузить изображение PNG, закодированное в Base64, в элемент холста. У меня есть такой код:

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

В Chrome 8 появляется ошибка: Uncaught TypeError: Type error

А в Firebug Firefox это: «Тип объекта несовместим с ожидаемым типом параметра, связанного с объектом» code: «17»

В этом base64 находится черный квадрат PNG размером 5x5px, который я создал в GIMP и превратил его в base64 в программе base64 GNU / Linux.

Ответы:


171

Судя по всему, вам нужно передать drawImage объект изображения, например

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>

Я пробовал в хроме, и он отлично работает.


8
Хороший ответ, но уверены ли вы, что это работает каждый раз? Я обнаружил, что рисовать изображение сразу после установки src, потому что вы должны использовать onloadобратный вызов, чтобы гарантировать, что изображение завершило загрузку. 50% моих тестов не прошли, потому что изображение еще не загрузилось.
Скотт Риппи

Вот это да! Взрыв из прошлого :). Вы совершенно правы. Если вы вызываете drawImage сразу после того, как вы установили src изображения, у вас, вероятно, возникнут проблемы, и в зависимости от вашей ситуации вы, скорее всего, захотите использовать onload, чтобы убедиться, что изображение действительно загружено, прежде чем вы попытаетесь визуализировать это на холст. Приведенный выше код был просто еще одним примером, показывающим, что drawImage на самом деле требует объект изображения и как передать его ему.
Джерриф,

8
В качестве примечания: если вы перебираете несколько холстов, вы можете изменить его на, ctx.drawImage(this,0,0);чтобы переменная изображения ссылалась на правильное изображение. Хотя отличный ответ!
Соня

13
Событие onload должно быть установлено до src. Иногда src может быть загружен мгновенно и никогда не
запускать

3
Но, если data:image/длина будет большой, мы получим414 (Request-URI Too Long
Сарат

17

Ответ Джеррифа хорош, за исключением одного недостатка.

Событие onload должно быть установлено до src. Иногда src можно загрузить мгновенно и никогда не запускать событие onload.

(Как указал 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
Кстати: Я отредактировал ответ Джеррифа, но кто-то его отклонил. Это не мог быть Джерриф, поскольку в его профиле указано, что последний раз он входил в систему в 2014 году.
Джон,

2
«Иногда src можно загрузить мгновенно и никогда не запускать событие onload». Я думаю, что такое случается крайне редко или почти никогда, но нет причин не сделать это привычкой, которую нужно установить onloadраньше src... Я делаю это привычкой.
markE

2
@markE Это не редкость. Это будет происходить постоянно, когда браузер кэширует изображение, например, при перезагрузке браузера. Это произошло в движке IE в программе на C ++.
Стефан Рейн,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.