FabricJS 将 json 转换为 png

Ann*_*lee 5 javascript node.js fabricjs node-canvas

我创建了以下图像作为fabricjs-json:

在此输入图像描述

json 如下所示:

{
    "version": "5.2.1",
    "objects": [
        {
            "type": "circle",
            "version": "5.2.1",
            "originX": "center",
            "originY": "center",
            "left": "100",
            "top": "100",
            "width": "60",
            "height": "60",
            "fill": "#e53e3e",
            "name": "a",
            "radius": "30",
            "stroke": null,
            "padding": "0"
        },
        {
            "type": "triangle",
            "version": "5.2.1",
            "originX": "center",
            "originY": "center",
            "left": "80",
            "top": "229.13",
            "fill": "#e0da2e",
            "name": "b",
            "height": "100",
            "width": "100",
            "stroke": null,
            "padding": "0"
        },
        {
            "type": "rect",
            "version": "5.2.1",
            "originX": "center",
            "originY": "center",
            "left": "303.02",
            "top": "69.96",
            "width": "50",
            "height": "50",
            "fill": "#4976d0",
            "name": "c",
            "rx": "0",
            "ry": "0",
            "stroke": null,
            "padding": "0"
        },
        {
            "type": "image",
            "version": "5.2.1",
            "originX": "center",
            "originY": "center",
            "left": "272.23",
            "top": "287.63",
            "width": "400",
            "height": "400",
            "scaleX": "0.58",
            "scaleY": "0.58",
            "name": "d",
            "rx": "0",
            "ry": "0",
            "stroke": null,
            "padding": "0",
            "src": "https:\/\/picsum.photos\/id\/1014\/400",
            "crossOrigin": null
        },
        {
            "type": "textbox",
            "version": "5.2.1",
            "originX": "center",
            "originY": "center",
            "left": "210.97",
            "top": "100",
            "width": "265.14180221557615",
            "height": "25.99",
            "fill": "#000000",
            "angle": "33.4",
            "name": "e",
            "text": "This awesome image",
            "textAlign": "left",
            "fontSize": "23",
            "charSpacing": "7",
            "lineHeight": "1.16",
            "fontWeight": "400",
            "fontFamily": "Inter",
            "fontStyle": "normal",
            "textBackgroundColor": null,
            "maxHeight": "487",
            "stroke": null,
            "padding": "20"
        }
    ],
    "background": "#24bd0f"
}

Run Code Online (Sandbox Code Playgroud)

我创建了以下脚本来将 json 转换为图像:

var fs = require('fs'),
    fabric = require('fabric').fabric,
    out = fs.createWriteStream(__dirname + '/output.png');

let jsonstr = fs.readFileSync(__dirname + '/json/test_json.json', 'utf-8');
let json = JSON.parse(jsonstr);

var canvas = new fabric.StaticCanvas(null, { width: 500, height: 500 });

canvas.loadFromJSON(json, function() {

    canvas.renderAll.bind(canvas);

    var dataUrlOutput = canvas.toDataURL(); // png is default format
    console.log(dataUrlOutput)
    fs.writeFile(__dirname + '/output/output.png', dataUrlOutput, function(err) {
        if (err) throw err;
    });
});

Run Code Online (Sandbox Code Playgroud)

这是我的package.json

{
  "name": "jsonToImage",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "canvas": "^2.9.3",
    "fabric": "^5.2.4"
  }
}

Run Code Online (Sandbox Code Playgroud)

但是,当打开图像时我得到:

在此输入图像描述

我创建了以下沙箱来解析 json:

Codesandbox 示例 - JSONtoIMAGE

有什么建议我做错了什么吗?

更新

我检查了dataUrlOutput 脚本并得到以下信息:

在此输入图像描述

正如您所看到的,一半的元素都在那里。

Ste*_*eve 3

似乎发生了一些事情,即 JSON 的格式化、渲染画布以及将文件保存在 Node.js 中。

格式化您的 JSON

json 文件中的数字用引号括起来(例如"left": "100"),而对于这些数值,fabric.js 希望它们不要用引号括起来(例如"left": 100)。当数字周围有引号时,fabric.js 似乎会准加载某些对象,但不会加载其他对象。

当您将画布另存为 JSON 时,您可以使用JSON.stringify来确保保留格式。例如,JSON.stringify(canvas.toJSON());

渲染画布

您正在调用canvas.renderAll.bind(canvas),这会创建一个新函数但不会调用它。应该只是这样canvas.renderAll()

保存图像

直接将数据 url 保存为文本文件不会在编码的二进制文件中创建图像。虽然您可以使用数据 url 创建二进制文件(如此答案中所示),但 Fabric.js 添加了一些方便的函数来保存文件,即canvas.createPNGStream().

它看起来像这样(感谢这个答案):

var out = fs.createWriteStream(__dirname + '/output.png');
var stream = canvas.createPNGStream();
stream.pipe(out);
Run Code Online (Sandbox Code Playgroud)

全部一起

使用修改后的 JSON 和代码,结果如下所示:

您的数据文件,'json/test_json.json'

{
    "version": "5.2.1",
    "objects": [
        {
            "type": "circle",
            "version": "5.2.1",
            "originX": "center",
            "originY": "center",
            "left": 100,
            "top": 100,
            "width": 60,
            "height": 60,
            "fill": "#e53e3e",
            "name": "a",
            "radius": 30,
            "stroke": null,
            "padding": 0
        },
        {
            "type": "triangle",
            "version": "5.2.1",
            "originX": "center",
            "originY": "center",
            "left": 80,
            "top": 229.13,
            "fill": "#e0da2e",
            "name": "b",
            "height": 100,
            "width": 100,
            "stroke": null,
            "padding": 0
        },
        {
            "type": "rect",
            "version": "5.2.1",
            "originX": "center",
            "originY": "center",
            "left": 303.02,
            "top": 69.96,
            "width": 50,
            "height": 50,
            "fill": "#4976d0",
            "name": "c",
            "rx": 0,
            "ry": 0,
            "stroke": null,
            "padding": 0
        },
        {
            "type": "image",
            "version": "5.2.1",
            "originX": "center",
            "originY": "center",
            "left": 272.23,
            "top": 287.63,
            "width": 400,
            "height": 400,
            "scaleX": 0.58,
            "scaleY": 0.58,
            "name": "d",
            "rx": 0,
            "ry": 0,
            "stroke": null,
            "padding": 0,
            "src": "https:\/\/picsum.photos\/id\/1014\/400",
            "crossOrigin": null
        },
        {
            "type": "textbox",
            "version": "5.2.1",
            "originX": "center",
            "originY": "center",
            "left": 210.97,
            "top": 100,
            "width": 265.14180221557615,
            "height": 25.99,
            "fill": "#000000",
            "angle": 33.4,
            "name": "e",
            "text": "This awesome image",
            "textAlign": "left",
            "fontSize": 23,
            "charSpacing": 7,
            "lineHeight": 1.16,
            "fontWeight": 400,
            "fontFamily": "Inter",
            "fontStyle": "normal",
            "textBackgroundColor": null,
            "maxHeight": 487,
            "stroke": null,
            "padding": 20
        }
    ],
    "background": "#24bd0f"
}
Run Code Online (Sandbox Code Playgroud)

还有你的node.js程序:

var fs = require('fs'),
    fabric = require('fabric').fabric,
    out = fs.createWriteStream(__dirname + '/output.png');

let jsonstr = fs.readFileSync(__dirname + '/json/test_json.json', 'utf-8');
let json = JSON.parse(jsonstr);

var canvas = new fabric.StaticCanvas(null, { width: 500, height: 500 });

canvas.loadFromJSON(json, function() {
    canvas.renderAll();
    var stream = canvas.createPNGStream();
    stream.pipe(out);
    out.on('finish', function () {
        // do something here
    });
});
Run Code Online (Sandbox Code Playgroud)

更多阅读:

http://fabricjs.com/fabric-intro-part-4(“Node.js上的 Fabric”部分)