2

這裏是我嘗試使用節點和imagemagick轉換工具將svg字符串轉換爲png緩衝區。然後使用pdfkit使用png緩衝區在pdf中繪製圖像。使用Node.js處理大型流

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字符串爲「小」(如在所提供的示例上) - 我不知道從哪裏從小截止到大的。

但是,當試圖使用更大的svg字符串(您可能使用D3生成的東西)就像這樣[large string]。我碰到:

Error: Incomplete or corrupt PNG file

所以我的問題是:如何確保convert子進程處理之前讀取整個流?

有幾件事情是已知的:

  • 的PNG緩存確實不完全。我使用diff工具來檢查 由應用程序 生成的base64字符串與在線的png-to-svg轉換器的base64字符串。未損壞的 字符串比損壞的字符串大得多。 (對不起,我沒有 更具體的文件大小)。也就是說,轉換工具似乎 在任何時候都不會讀取整個源文件。

  • 源SVG字符串沒有被破壞(如由這一事實的 要旨渲染它)

  • 當在命令行中使用的轉換工具正確地生成從SVG一個 PNG文件「stream」與cat large_svg.svg | convert svg:png:-因此,這是不是轉換工具的問題。

這導致我下降一個節點的緩衝區大小爲可寫和可讀流的兔子洞,但無濟於事。也許有人曾在節點中使用較大的流,可以幫助開展工作。

+4

你必須緩衝輸出**,直到過程結束** *從不*假設*塊的大小*傳遞給''data''事件處理程序。它可能是1個字節,也可能是1兆字節。 – mscdex

+0

謝謝!工作,我只需要研究如何連接緩衝區。 – putonspectacles

回答

2

@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參數,以幫助緩衝區大小分配連接塊時。

// 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 


} 
+1

更有效的方法是將數據塊附加到數據處理程序中的數組,然後在「end」處理程序中調用Buffer.concat()。如果你希望更高效,你可以保持一個可以傳遞給Buffer.concat()而不是強制「Buffer.concat()」的塊大小的動態計算需要的長度。 – mscdex