如何将画布数据保存到文件

sw-*_*dev 35 javascript html5 node.js

我使用node.js将画布保存到imageFile中的图像img是使用我的canvas元素上的toDataURL提取的.它doenot保存文件在这里是我的代码

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.'
        });
    }
 });    
Run Code Online (Sandbox Code Playgroud)

sam*_*ias 43

下面是如何将画布数据保存到 Nodejs中的文件的文字示例.变量img是由...生成的字符串canvas.toDataURL().我假设您已经知道如何将该字符串从浏览器发布到Nodejs服务器.

生成我使用的示例图像的HTML代码段:

<canvas id="foo" width="20px" height="20px"></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>
Run Code Online (Sandbox Code Playgroud)

Nodejs片段解码base64数据并保存图像:

fs = require('fs');
sys = require('sys');
// string generated by canvas.toDataURL()
var img = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0"
    + "NAAAAKElEQVQ4jWNgYGD4Twzu6FhFFGYYNXDUwGFpIAk2E4dHDRw1cDgaCAASFOffhEIO"
    + "3gAAAABJRU5ErkJggg==";
// strip off the data: url prefix to get just the base64-encoded bytes
var data = img.replace(/^data:image\/\w+;base64,/, "");
var buf = new Buffer(data, 'base64');
fs.writeFile('image.png', buf);
Run Code Online (Sandbox Code Playgroud)

输出:

在此输入图像描述

  • `new Buffer` 已被弃用 [per nodejs](https://nodejs.org/en/docs/guides/buffer-constructor-deprecation/)。在这种情况下,您现在应该使用 `Buffer.from(data, 'base64');`。 (4认同)
  • 对我来说,`toDataUrl()`字符串包含加上`body-parser`在`request.body`中变成空格的符号,所以我不得不再用加号替换它们以便我的png没有损坏:`var数据= img.slice(img.indexOf( ' ')+ 1).replace(/\S/G,' +');` (2认同)

Dan*_*Dan 18

我相信它Canvas不会在内部将它的数据存储在Base64中.它应该以更高效的二进制格式存储数据.因此,显然,转移到base64并返回到二进制PNG非常慢且占用内存.

快速搜索到节点画布文档提供:

要创建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');
});
Run Code Online (Sandbox Code Playgroud)

目前仅支持同步流.如果你想做异步,你可以尝试使用工作者或集群(我个人从未尝试过).

  • 这个答案更好/更清洁/更强. (2认同)