Base64 PNG 数据到 HTML5 画布

Posted

技术标签:

【中文标题】Base64 PNG 数据到 HTML5 画布【英文标题】:Base64 PNG data to HTML5 canvas 【发布时间】:2011-05-23 12:09:37 【问题描述】:

我想将一个以 Base64 编码的 PNG 图像加载到画布元素。我有这个代码:

<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

而在 Firefox 的 Firebug 中:“对象的类型与与对象关联的参数的预期类型不兼容”代码:“17”

base64 是我在 GIMP 中制作的 5x5px 黑色 PNG 正方形,然后在 GNU/Linux 的程序 base64 中将其转换为 base64。

【问题讨论】:

【参考方案1】:

从外观上看,您实际上需要像这样将 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";
&lt;canvas id="c"&gt;&lt;/canvas&gt;

我在 chrome 中试过了,效果很好。

【讨论】:

很好的答案,但你确定这每次都有效吗?我发现在设置src 后立即绘制图像有问题,因为您应该使用onload 回调来确保图像已完成加载。我的 50% 的测试都失败了,因为图片还没有完成加载。 哇!过去的爆炸:)。你说得很对。如果您在设置图像的 src 之后立即调用 drawImage,您可能会遇到问题,并且根据您的情况,您很可能希望使用 onload 来确保在尝试渲染之前实际加载了图像它到画布上。上面的代码只是一个示例,显示 drawImage 实际上需要一个图像对象以及如何将其传递给它。 请注意,如果您正在循环多个画布,您可能需要将其更改为ctx.drawImage(this,0,0);,以确保图像变量引用正确的图像。不过答案很好! onload事件应该设置在src之前。有时 src 可以立即加载并且永远不会触发 onload 事件 但是,如果data:image/ 的长度很大,我们将得到414 (Request-URI Too Long【参考方案2】:

Jerryf 的回答很好,除了一个缺陷。

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

【讨论】:

顺便说一句:我编辑了 Jerryf 的答案,但有人拒绝了它。不可能是 Jerryf,因为他的个人资料显示他最后一次登录是在 2014 年。 “有时 src 可以立即加载,并且永远不会触发 onload 事件。” 我认为这种情况的发生极为罕见,几乎从未发生,但没有理由不这样做养成在src 之前设置onload 的习惯...我养成了这样做的习惯。 @markE 这并不罕见。当浏览器缓存图像时,它会一直发生,例如在浏览器重新加载时。这发生在 C++ 程序中的 IE 引擎中。

以上是关于Base64 PNG 数据到 HTML5 画布的主要内容,如果未能解决你的问题,请参考以下文章

从base64数据字符串保存画布图像服务器端时,它会产生空白图像

jCrop HTML5 Canvas Base64

Safari 中的数据 URI 泄漏(原为:HTML5 画布的内存泄漏)

将fabricjs画布转换为base64图像

如何将 base64 编码的图像保存到磁盘?

如何将画布数据 uri 上传到亚马逊 s3 服务器