如何将画布数据保存到文件
Posted
技术标签:
【中文标题】如何将画布数据保存到文件【英文标题】:how to save canvas data to file 【发布时间】:2011-08-17 13:47:11 【问题描述】:我正在使用 node.js 将画布保存到图像 writeFile 中的 img 是通过在我的画布元素上使用 toDataURL 提取的。 它不保存文件 这是我的代码
var fs = IMPORTS.require('fs');
var path = IMPORTS.require('path');
path.exists('images/', function(exists)
if (exists)
fs.writeFile('images/icon.png', img, function(err)
if (err)
callback(
error: false,
reply: err
);
console.log('Resized and saved in');
callback(
error: false,
reply: 'success.'
);
);
else
callback(
error: true,
reply: 'File did not exist.'
);
);
【问题讨论】:
您能否包含您的画布代码或您正在测试的 url,以便我们无需编写任何样板即可运行您的代码? (请参阅sscce.org)如果您希望人们提供帮助,您可能还需要详细说明您的描述。 【参考方案1】:这是一个如何在 Nodejs 中将画布数据保存到文件的文字示例。变量img
是canvas.toDataURL()
生成的字符串。我假设您已经知道如何将该字符串从浏览器发布到您的 Nodejs 服务器。
生成我使用的示例图像的 html sn-p:
<canvas id="foo" ></canvas>
<script>
var ctx = $('#foo')[0].getContext('2d');
for (var x = 0; x < 20; x += 10)
for (var y = 0; y < 20; y += 10)
if (x == y) ctx.fillStyle = '#000000';
else ctx.fillStyle = '#8888aa';
ctx.fillRect(x, y, 10, 10);
console.log($('#foo')[0].toDataURL());
</script>
Nodejs sn -p 解码base64数据并保存图片:
const fs = require("fs").promises;
(async () =>
// string generated by canvas.toDataURL()
const img = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0"
+ "NAAAAKElEQVQ4jWNgYGD4Twzu6FhFFGYYNXDUwGFpIAk2E4dHDRw1cDgaCAASFOffhEIO"
+ "3gAAAABJRU5ErkJggg==";
// strip off the data: url prefix to get just the base64-encoded bytes
const data = img.replace(/^data:image\/\w+;base64,/, "");
const buf = Buffer.from(data, "base64");
await fs.writeFile("image.png", buf);
)();
输出:
【讨论】:
谢谢!我不知道我需要Buffer
,我只是想将base64.decode()
与base64 数据一起使用,但生成了一个损坏的文件。
服务器代码示例对我有用。有人可以解释一下为什么它不适用于这些数据:pastebin.com/raw.php?i=3yhGiQWR
我的缓冲区未定义
对我来说,toDataUrl()
字符串包括加号,body-parser
在request.body
中变成了空格,所以我不得不再次用加号替换它们,这样我的 png 就不会损坏: var data=img.slice(img.indexOf(',')+1).replace(/\s/g,'+');
new Buffer
已被弃用 per nodejs。在这种情况下,您现在应该使用Buffer.from(data, 'base64');
。【参考方案2】:
我相信Canvas
不会在内部将其数据存储在 Base64 中。它应该以更有效的二进制格式存储数据。因此,很明显,转换到 base64 再转换回二进制 PNG 非常缓慢且消耗内存。
快速搜索到node canvas documentation 给出:
要创建一个PNGStream,只需调用canvas.pngStream(),该流将开始发射数据事件,最后在完成时发射结束。如果发生异常,则会发出错误事件。
var fs = require('fs')
, out = fs.createWriteStream(__dirname + '/text.png')
, stream = canvas.pngStream();
stream.on('data', function(chunk)
out.write(chunk);
);
stream.on('end', function()
console.log('saved png');
);
目前仅支持同步流式传输。如果您想异步执行,可以尝试使用工作线程或集群(我个人从未尝试过)。
【讨论】:
这个答案更好/更干净/更强。 console.log('saved png') 发生在文件保存之前。这是因为只支持同步吗? 文件保存后如何触发事件?以上是关于如何将画布数据保存到文件的主要内容,如果未能解决你的问题,请参考以下文章
如何将使用 InkCanvas 在画布上完成的工作保存到 UWP C# 中的图像文件?