使用Node.JS和Fabric.JS - 将画布导出为PNG/JPEG格式

3

我正在使用 Fabric.JS 进行 Node.JS 的开发,而不是用在网页上。我已经成功创建了一个静态画布并在上面添加了一个矩形。现在是导出的时候了。以下是我的代码:

var canvas = new fabric.StaticCanvas(null, {width: 200, height: 200})
var rect = new fabric.Rect({
  left: 100,
  top: 100,
  width: 100,
  height: 50,
  fill: "red"
})
canvas.add(rect)

以下是我尝试过的所有导出图像的方法:

//Creates a PNG file that isn't generated correctly. It's as if it's corrupt. No program can open it
canvas.createPNGStream().on("data", function (chunk) {
  fs.createWriteStream(__dirname + "/output.png").write(chunk)
})

//Causes a crash
canvas.createJPEGStream().on("data", function (chunk) {
  fs.createWriteStream(__dirname + "/output.jpeg").write(chunk)
})

Error:
C:\Users\me\Documents\my project\node_modules\canvas\lib\jpegstream.js:44
    canvas[method](options.bufsize, options.quality, options.progressive, function(err, chunk){
                  ^

TypeError: canvas[method] is not a function
    at C:\Users\me\Documents\my project\node_modules\canvas\lib\jpegstream.js:44:19
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickCallback (internal/process/next_tick.js:180:9)

//Same thing as first try^^, except it's a JPEG
canvas.createJPEGStream({quality: 100}).pipe(fs.createWriteStream(__dirname + "/output.jpeg"))

//This one makes the PNG file, but when it's opened, its 100% transparent. That's it. The rectangle I added isn't there. Canvas size is correct, however
canvas.createPNGStream().pipe(fs.createWriteStream(__dirname + "/output.png"))

注意:在这种情况下,fabric.Canvas(null, {width: 200, height: 200}) 看起来与 StaticCanvas 完全相同。

注2:以下代码:

var canvas = new fabric.createCanvasForNode(200, 200)

导致此错误的结果为:

var canvas = new fabric.createCanvasForNode(200, 200)
             ^

TypeError: fabric.createCanvasForNode is not a constructor
    at Client.client.on.message (C:\Users\me\Documents\my project\index.js:31:14)
    at emitOne (events.js:115:13)
    at Client.emit (events.js:210:7)
    at MessageCreateHandler.handle (C:\Users\me\Documents\my project\node_modules\discord.js\src\client\websocket\packets\handlers\MessageCreate.js:9:34)
    at WebSocketPacketManager.handle (C:\Users\me\Documents\my project\node_modules\discord.js\src\client\websocket\packets\WebSocketPacketManager.js:103:65)
    at WebSocketConnection.onPacket (C:\Users\me\Documents\my project\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:330:35)
    at WebSocketConnection.onMessage (C:\Users\me\Documents\my project\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:293:17)
    at WebSocketClient.internalOnMessage (C:\Users\me\Documents\my project\node_modules\uws\uws.js:103:17)
    at native.client.group.onMessage (C:\Users\me\Documents\my project\node_modules\uws\uws.js:57:15)

我是否遗漏了什么?这些方法似乎都不起作用,这已经是我在Google上找到的所有信息了。导出图像的正确方式是什么?它可以是PNG或JPEG/JPG,最好是PNG,但JPEG/JPG也行。任何常用格式都可以。


1
查看此教程 在Node.js上使用Fabric - Durga
@Durga,是的,我已经尝试过PNGStream(问题中的第一次尝试)。 - APixel Visuals
创建画布使用 var canvas = fabric.createCanvasForNode(200, 200); 教程中有完整的代码,请尝试。 - Durga
@Durga 刚刚编辑了我的问题,在底部加了一条关于 fabric.createCanvasForNode 错误的注释。 - APixel Visuals
我明白了,它被移除了,然后 new fabric.StaticCanvas(null, {width: 200, height: 200}) 这个会起作用。我会检查剩下的部分,并让你知道。 - Durga
@Durga 在我的情况下,fabric.Canvas 的工作方式与 StaticCanvas 完全相同。 - APixel Visuals
3个回答

2

找到了答案。 canvas.createPNGStream().pipe(fs.createWriteStream(__dirname + "/output.png")) 实际上是有效的。它完全为空的原因是因为看起来像 canvas.add() 不是即时操作。我做的所有事情就是在输出文件之前使用了一个 setTimeout()。希望这能帮助到某些人!


0

我使用了来自node-canvas的示例代码,它可以正常工作。

const fs = require('fs')
const out = fs.createWriteStream(__dirname + '/test.png')
const stream = canvas.createPNGStream()
stream.pipe(out)
out.on('finish', () =>  console.log('The PNG file was created.'))

0

就像在这个教程中,由Durga分享的,你忘记使用canvas.renderAll();

加上这个修复了我的问题。

完整代码:

var canvas = new fabric.StaticCanvas(null, {width: 200, height: 200})
var rect = new fabric.Rect({
  left: 100,
  top: 100,
  width: 100,
  height: 50,
  fill: "red"
})
canvas.add(rect);
canvas.renderAll();
canvas.createPNGStream().pipe(fs.createWriteStream("./output.png"))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接