Подтвердить что ты не робот

Поток, загружающий gm-resized изображение в s3 с помощью aws-sdk

так что я хочу сделать, это потоковое изображение с URL-адреса, обработать его графикой и загрузить его на s3. я просто не работаю.

потоковая передача обработанного изображения на локальный диск (с использованием fs.createWriteStream) работает без проблем.

когда я буфера моего потока, окончательное изображение в s3 имеет как минимум ожидаемый размер (kb-мудрый), но я не могу открыть это изображение.

это мой текущий прогресс:

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

Я попробовал кое-что вроде создания файлового потока и filereadstream, но я думаю, что должно быть какое-то более чистое решение этой проблемы...

EDIT: первое, что я попробовал, - установить Body на stdout (предлагаемый ответ от @AndyD):

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

но возвращает следующую ошибку:

Cannot determine length of [object Object]'

EDIT2:

  • nodeversion: 0.8.6 (я также пробовал 0.8.22 и 0.10.0)
  • aws-sdk: 0.9.7-pre.8 (установлен сегодня)

полное err:

{ [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' }
4b9b3361

Ответ 1

вам не нужно самостоятельно читать поток (в вашем случае вы, кажется, конвертируете из двоичного кода в строку и обратно из-за var str = '', а затем добавляете данные, которые являются двоичным буфером и т.д.

Попробуйте putObject передать поток следующим образом:

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

Подробнее см. в этих примечаниях к выпуску.

Если потоковая передача/труба не работает, то что-то вроде этого может загрузить все в память, а затем загрузить. В этом случае вы ограничены 4Mb.

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