2013-04-04 19 views
14

quindi quello che voglio fare è lo streaming di un'immagine da un URL, elaborarlo con graphicsmagick e caricare lo streaming su s3. semplicemente non lo faccio funzionarestream uploading un'immagine gm-ridimensionata a s3 con aws-sdk

lo streaming dell'immagine su disco locale (utilizzando fs.createWriteStream) funziona senza problemi.

quando bufferizzo il flusso, l'immagine finale in s3 ha almeno la dimensione prevista (kb-saggio), ma non riesco ad aprire quell'immagine.

thats il mio progresso attuale:

var request = require('request'); 

var gm = require("gm"); 

var AWS = require('aws-sdk'); 

var mime = require('mime'); 

var s3 = new AWS.S3(); 

gm(request('http://www.some-domain.com/some-image.jpg'), "my-image.jpg") 
    .resize("100^", "100^") 
    .stream(function(err, stdout, stderr) { 
    var str = ''; 
    stdout.on('data', function(data) { 
     str += data; 
    }); 
    stdout.on('end', function(data) { 
     var data = { 
     Bucket: "my-bucket", 
     Key: "my-image.jpg", 
     Body: new Buffer(str, 'binary'), // thats where im probably wrong 
     ContentType: mime.lookup("my-image.jpg") 
     }; 
     s3.client.putObject(data, function(err, res) { 
     console.log("done"); 
     }); 
    }); 
    }); 

ho provato alcune cose, come la creazione di un filewritestream e filereadstream, ma penso che ci dovrebbe essere una più pulito una soluzione più bello di quel problema ...

EDIT : la prima cosa che ho provato è stata l'impostazione del corpo a stdout (la risposta suggerita da @AndyD):

var data = { 
    Bucket: "my-bucket", 
    Key: "my-image.jpg", 
    Body: stdout, 
    ContentType: mime.lookup("my-image.jpg") 
    }; 

ma che restituisce seguente errore:

Cannot determine length of [object Object]' 

EDIT2:

  • nodeversion: 0.8.6 (ho anche provato 0.8.22 e 0.10.0)
  • AWS-sdk: 0.9.7-pre.8 (oggi installato)

l'err completo:

{ [Error: Cannot determine length of [object Object]] 
    message: 'Cannot determine length of [object Object]', 
    object: 
    { _handle: 
    { writeQueueSize: 0, 
    owner: [Circular], 
    onread: [Function: onread] }, 
_pendingWriteReqs: 0, 
_flags: 0, 
_connectQueueSize: 0, 
destroyed: false, 
errorEmitted: false, 
bytesRead: 0, 
_bytesDispatched: 0, 
allowHalfOpen: undefined, 
writable: false, 
readable: true, 
_paused: false, 
_events: { close: [Function], error: [Function: handlerr] } }, 
name: 'Error' } 

risposta

12

non c'è bisogno di ri da solo (nel tuo caso sembra che tu stia convertendo da binario a stringa e viceversa a causa di var str = '' e poi aggiungendo dati che sono un buffer binario ecc ...

Prova a mettere il pipe a pipe come questo:

gm(request('http://www.some-domain.com/some-image.jpg'), "my-image.jpg") 
    .resize("100^", "100^") 
    .stream(function(err, stdout, stderr) { 
     var data = { 
     Bucket: "my-bucket", 
     Key: "my-image.jpg", 
     Body: stdout 
     ContentType: mime.lookup("my-image.jpg") 
     }; 
     s3.client.putObject(data, function(err, res) { 
     console.log("done"); 
     }); 
    }); 
    }); 

Vedere questi release notes per ulteriori informazioni.

Se lo streaming/pipe non funziona, qualcosa del genere potrebbe caricare tutto in memoria e quindi caricare. Sei limitato a 4 Mb credo in questo caso.

var buf = new Buffer(''); 
    stdout.on('data', function(data) { 
     buf = Buffer.concat([buf, data]); 
    }); 
    stdout.on('end', function(data) { 
     var data = { 
     Bucket: "my-bucket", 
     Key: "my-image.jpg", 
     Body: buf, 
     ContentType: mime.lookup("my-image.jpg") 
     }; 
     s3.client.putObject(data, function(err, res) { 
     console.log("done"); 
     }); 
    }); 
+0

questa è stata la prima cosa che ho provato, perché lo stdout dovrebbe già essere uno stream giusto? ma non funziona, 'err' nell'ultimo callback dice 'Non posso determinare la lunghezza di [oggetto Object]' ;-( – hereandnow78

+0

hai uno stacktrace? Stai usando l'ultima versione di aws-SDK? – AndyD

+0

vedi il mio secondo edit – hereandnow78

Problemi correlati