2012-08-01 4 views
5

Używam Express.js i mam trasę do przesyłania zdjęć, które muszę zmienić. Obecnie po prostu pozwalam Express zapisywać plik na dysku (który, jak myślę, używa node-formidable pod okładkami), a następnie zmienić rozmiar, używając gm (http://aheckmann.github.com/gm/), który zapisuje drugą wersję na dysku.Plik strumieniowy przesłany za pomocą Express.js przez gm, aby wyeliminować podwójne pisanie

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

Czytałem, że można dorwać strumienia node-formidable plików przed zapisuje go na dysku, a od gm może zaakceptować strumień zamiast tylko ścieżki, powinienem być w stanie przekazać tego prawa poprzez wyeliminowanie podwójnego zapisu na dysk.

Chyba trzeba zastąpić form.onPart ale nie jestem pewien, gdzie (powinno to być zrobione jak Express middleware?) I nie jestem pewien, jak się trzymać z form czy co dokładnie zrobić z part. To jest szkielet kodu, który widziałem w kilku miejscach:

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

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

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

    } 
} 

Czy ktoś może mi pomóc złożyć te dwa kawałki razem? Dzięki!

Odpowiedz

7

Jesteś na dobrej drodze, przepisując form.onPart. Formidable zapisuje na dysku domyślnie, więc chcesz działać przed nim.

Części same w sobie są strumieniami, więc można je przesyłać dowolnie, w tym gm. Nie testowałem go, ale ma to sens na podstawie dokumentacji:

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')); 
    }); 
}; 

chodzi o middleware, bym CopyPaste się multipart middleware od Połącz/Express i dodać funkcję onPart do niego:

Byłoby o wiele ładniej, gdyby formidable nie zapisywał się na dysku domyślnie lub gdyby wziął flagę, prawda? Możesz wysłać im problem.

+0

Dziękujemy! Dało mi to 95% drogi. Mój ostatni problem polega na tym, że 'gm' jest asynchroniczne, a więc parsowanie formularzy powraca przed faktycznym zakończeniem zmiany rozmiaru (co oznacza, że ​​adres URL, który miałem z powrotem do klienta, nie jest jeszcze dobry). Czy istnieje sposób na poinformowanie 'strasznego ', gdy obsługa' part' jest rzeczywiście zakończona? – Bill

+0

Właściwie to właśnie skończyłem obsługę tego na kliencie - działa lepiej w ten sposób. Dzięki jeszcze raz! – Bill

+1

stdout jest strumieniem. Dlatego możesz potokować() do pliku WriteStream. A to oznacza, że ​​ma "końcowe" wydarzenie, którego możesz słuchać. Po prostu wykonaj stdout.on ('end', fn) i wtedy możesz powiedzieć klientowi, że zadanie zostało wykonane. – juandopazo

Powiązane problemy