javascript - 使用 Node.js 处理大流

标签 javascript node.js pdf-generation imagemagick-convert pdfkit

这是我尝试使用 Node 和 imagemagick 转换工具将 svg 字符串转换为 png 缓冲区。然后使用 pdfkit 使用 png 缓冲区在 pdf 中绘制图像。

Td;lr 我有一个大的 svg 字符串,需要访问“整个”子进程(即未分块)。我该怎么做?

这是一个适用于小文件的示例。

var child_process = require('child_process');
var pdfDocument = require('pdfkit');


var convert = child_process.spawn("convert", ["svg:", "png:-"]),
svgsrc =  '<svg><rect height="100" width="100" style="fill:red;"/></svg>';

convert.stdout.on('data', function(data) {  
    console.log(data.toString('base64')
    doc = new pdfDocument()
    doc.image(data)
}


convert.stdin.write(svgsrc);
convert.stdin.end()

当 svg 字符串为“小”时(如示例中提供的 on),此方法有效 - 我不确定从小到大的截止点在哪里。

但是,当尝试使用更大的 svg 字符串(您可能使用 D3 生成的字符串)时,如下所示 [ large string ]。我遇到:

Error: Incomplete or corrupt PNG file

所以我的问题是:如何确保 convert 子进程在处理之前读取整个流?

有几件事是已知的:

  • png 缓冲区确实不完整。我使用 diff 工具来检查 应用程序生成的base64字符串 与在线 png 到 svg 转换器的 base64 对比。未腐败的 字符串比损坏的字符串大得多。 (抱歉我没有 文件大小更加具体)。也就是说,转换工具似乎 在任何给定时间都不阅读整个源代码。

  • 源 svg 字符串未损坏(事实证明 gist 渲染了它)

  • 在命令行中使用时,转换工具会正确生成 来自 svg“流”的 png 文件,带有 cat large_svg.svg |转换 svg:png:- 所以这不是转换工具的问题

这让我陷入了一个兔子洞,寻找 Node 的缓冲区大小以查找可写和可读流,但无济于事。也许有人在 Node 中处理过更大的流,并且可以帮助让其正常工作。

最佳答案

正如 @mscdex 指出的那样,我必须等待该过程完成才能完成 尝试下游工作。所需要的只是等待 convert.stdout 流上的 end 事件并连接 data 事件上的缓冲区。

// allocate a buffer of size 0
graph = Buffer.alloc(0)

// on data concat the incoming and the `graph`

convert.stdout.on('data', function(data) {

    graph = Buffer.concat([graph, data])
}
convert.stdout.on('end', function(signal) {

    // ... draw on pdf

}

编辑:

这是上面的一个更有效的版本,我们使用 @mscdex 建议在 end 回调上进行串联,并保留 chunksize 参数,以帮助缓冲区在串联 block 时分配大小。

// allocate a buffer of size 0
var graph = [];
var totalchunks = 0;

convert.stdout.on('data', function(data) {

    graph.push(data);
    totalsize +=data.length;
}
convert.stdout.on('end', function(signal) {

    var image = Buffer.concat(graph, totalsize);
    // ... draw on pdf


}

关于javascript - 使用 Node.js 处理大流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43727457/

相关文章:

java - 如何使用 PDFBox drawString 插入换行符

javascript - 如何使用 jQuery 或 Javascript 制作模态弹出窗口以获取输入值?

c# - 如何将用户重定向到不同的服务器并包含 HTTP 基本身份验证凭据?

javascript - 未捕获( promise 中)TypeError : Cannot set property of undefined at eval in vue. js?

node.js - 获取包含特定文件nodejs的所有第一个子文件夹

java - 为什么在 Linux 中 PDF 中的文本会被截断?

javascript - append/appendChild 不适用于所有项目

node.js - 如何使用node js从mongo获取记录中的特定信息?

javascript - 在 JavaScript 中,特别是 NodeJS 上的 ES6,我可以在运行时直接操作类的 getter 和 setter 函数吗?

java - 使用 iText 生成 pdf 的锚定方法的相对路径