Дані Base64 PNG на полотно 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

А у Firebux у Firebux це: "Тип об'єкта несумісний із очікуваним типом параметра, пов'язаного з об'єктом" код: "17"

У цьому base64 є чорний квадрат PNG розміром 5x5px, який я зробив у GIMP, і перетворюю його на base64 у програмі base64 GNU / Linux.

Відповіді:


170

За зовнішнім виглядом вам потрібно фактично передати 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
Подія завантаження повинна бути встановлена ​​перед src. Іноді сервер можна завантажити миттєво і ніколи не запускати подію завантаження
Totty.js

3
Але, якщо data:image/довжина велика, ми отримаємо414 (Request-URI Too Long
Сарат

17

Відповідь Джерріфа чудова, за винятком однієї вади.

Подія завантаження повинна бути встановлена ​​перед src. Іноді src можна завантажити миттєво і ніколи не запускати подію завантаження.

(Як зазначив 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раніше src... Я маю звичку це робити.
markE

2
@markE Це не рідкість. Це відбуватиметься весь час, коли браузер кешує зображення, наприклад при перезавантаженні браузера. Це сталося в двигуні IE у програмі на C ++.
Штефан Рейн,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.