2012-08-01 56 views
5

我使用Express.js並有一條上傳圖像的路線,然後我需要調整其大小。目前,我只是讓Express將文件寫入磁盤(我認爲使用下面的node-formidable),然後使用gm(http://aheckmann.github.com/gm/)將第二個版本寫入磁盤來調整大小。通過gm通過Express.js上傳流文件以消除雙重寫入

gm(path) 
    .resize(540,404) 
    .write(dest, function (err) { ... }); 

我讀過,你可以得到node-formidable文件流的保持它寫入到磁盤之前,由於gm可以接受流,而不僅僅是一個路徑,我應該能夠通過這一權利通過消除雙重寫入磁盤。

我想我需要重寫form.onPart,但我不知道在哪裏(如果它爲Express中間件?做),我不知道怎麼弄的form保持或正好做的part什麼。這是我在幾個地方見過的代碼骨架:

form.onPart = function(part) { 
    if (!part.filename) { form.handlePart(part); return; } 

    part.on('data', function(buffer) { 

    }); 
    part.on('end', function() { 

    } 
} 

有人能幫我把這兩塊拼在一起嗎?謝謝!

回答

7

您正在通過重寫form.onPart正確的方向。強大的寫入磁盤默認情況下,所以你想行事之前。

零件本身是流,所以你可以將它們管到任何你想要的,包括gm。我沒有測試過,但是這使得基於文檔的感覺:

var form = new formidable.IncomingForm; 
form.onPart = function (part) { 
    if (!part.filename) return this.handlePart(part); 

    gm(part).resize(200, 200).stream(function (err, stdout, stderr) { 
    stdout.pipe(fs.createWriteStream('my/new/path/to/img.png')); 
    }); 
}; 

至於中間件,我copypaste從連接/ Express中的multipart中間件,並添加onPart功能吧:

如果formidable默認情況下沒有寫入磁盤,或者如果它帶了一個標記,它會好很多,不是嗎?你可以給他們發一個問題。

+0

謝謝!這讓我有95%的途徑。我的最後一個問題是'gm'是異步的,所以在調整大小實際上完成之前,表單解析會返回(這意味着我返回到客戶端的url並不是很好)。有沒有辦法讓'強大'知道'part'處理是否真的完成了? – Bill 2012-08-03 23:49:53

+0

其實,我只是最終在客戶端處理了這個問題 - 這樣更好地解決問題。再次感謝! – Bill 2012-08-04 01:13:37

+1

stdout是一個Stream。這就是爲什麼你可以將它傳遞給一個WriteStream文件的原因。這意味着它有一個你可以聽到的「結束」事件。只要做stdout.on('end',fn),那就是當你可以告訴客戶工作完成了。 – juandopazo 2012-08-04 16:17:17