2013-10-24 13 views
2

У меня возникла проблема с манипуляцией изображением с помощью imagemagick, а затем загрузите его на S3. Получаемый объект имеет другой (больший) размер и, кажется, поврежден. Если я сделаю промежуточный шаг и сначала сохраню вывод в локальном файле tmp и прочитаю его, то загрузите результат, все будет хорошо. Это код, который НЕ работает.node.js загрузка вывода imagemagick в AWS S3

im.resize({ 
    srcData: imageObject.Body, 
    width: variant.width, 
    height: variant.height, 
    customArgs: ['-auto-orient'] 
}, function(err, stdout, stderr) { 
    if (err) { 
     // This resize completed successfully 
     log.err('Failed calling imageMagick, bail out', err); 
     callback(err); 
     return; 
    } 

    var fileName = cfg.aws.s3.uploadDir + 
        photo.imageId + '/' + 
        variant.width + 'x' + variant.height + '.jpg'; 
    log.info('Storing image at S3 ' + fileName); 
    //fs.writeFileSync('/tmp/xxx.jpg', stdout, 'binary'); 
    //stdout = fs.readFileSync('/tmp/xxx.jpg'); 
    var x = new Buffer(stdout); 
    console.log(x); 
    s3.putObject(
     { 
      Bucket: cfg.aws.s3.bucket, 
      Key: fileName, 
      Body: x, 
      ContentType: 'image/jpeg', 
      ACL: 'public-read' 
     }, 
     function(err, data) { 
      if (err) { 
       // Failed saving to S3 
       log.error('Failed saving to S3', err); 
      } 

      callback(err); 
     } 
    ); 
}); 

Раскомментировать файлWriteSync и fileReadSync, и он работает правильно.

Выход console.log (х) команды в двух случаях: ПЛОХО:

буфера с3 Б.Ф. с3 98 с3 Б.Ф. с3 а0 00 10 4a 46 49 46 00 01 01 01 00 01 00 01 00 00 c3 бф c3 9b 43 00 00 06 04 05 06 05 04 06 06 05 06 07 07 06 08 0a 10 0A 0A 09 09 ...>

ХОРОШО:

Буфер ff d 8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 01 00 01 00 00 ff db 00 43 00 06 04 05 06 05 04 06 06 05 06 07 07 06 08 0a 10 0a 0a 09 09 0a 14 0e 0f 0C 10 ...>

, как вы можете видеть хорошие один является собственным JPEG, плохой один, хотя содержит сходные последовательности, как 4a 46 49 46 = JFIF, однако некоторые байты выключены, и есть сдвиги, то весь файл больше на 20% в плохом случае.

Что-то общего с кодировкой? Я пробовал несколько вещей, но я потерялся в этот момент.

Спасибо!

Update # 1: Видимо, это связано с кодировкой UTF, но я до сих пор не совсем понимаю, что происходит в данном случае. По-видимому с3 Б.Ф. с3 98 с3 Б.Ф. с3 а0 00 10 4a 46 49 46 00 01 UTF кодирование:

U+00FF LATIN SMALL LETTER Y WITH DIAERESIS character (ÿ) 
U+00D8 LATIN CAPITAL LETTER O WITH STROKE character (Ø) 
U+00FF LATIN SMALL LETTER Y WITH DIAERESIS character (ÿ) 
U+00E0 LATIN SMALL LETTER A WITH GRAVE character (à) 
U+0000 <control> character 
U+0010 <control> character 
U+004A LATIN CAPITAL LETTER J character 
U+0046 LATIN CAPITAL LETTER F character 
U+0049 LATIN CAPITAL LETTER I character 
U+0046 LATIN CAPITAL LETTER F character 
U+0000 <control> character 
U+0001 <control> character 

когда FF D8 FF .. именно то, что я ожидал.

Я знаю, как сделать код работу без временных файлов (заменить вар х = новый буфер (стандартный вывод); с варом х = новый буфер (стандартный вывод «двоичный»))

Однако я все еще не могу сказать, что я полностью понимаю, что здесь произошло, это должно быть без упаковки Buffer(), у какого компонента есть проблема? ImageMagick? Буфер?

+0

Ого, это странно вопрос. Хорошо сформулированный вопрос и интересная проблема. Я посмотрю, смогу ли я это узнать сегодня:) –

+0

Просто из любопытства, что произойдет, если вы не поместите stdout в новый объект буфера? он выходит из node-imagemagick как строка? Если он все равно выйдет в виде буфера, коррупция может быть двойной буферной оболочкой ... –

+0

Вы пытались «Тело: stdout», в ваших параметрах putObject просто отправлять stdout без упаковки в ненужный буфер? –

ответ

0

Не уверен, что ОП решила проблему, но у меня тоже была аналогичная проблема, когда изображения, загруженные на S3, были больше, чем исходные файлы. Не могли бы вы рассказать мне, что содержит stdout (т. Е. Является ли он сырым байтовым потоком?)

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

схемы кодирования Base64 обычно используются, когда есть необходимость кодировать двоичные данные, которые должны быть сохранены и переданы которые предназначены для обработки текстовых данных. Это делается для того, чтобы данные сохранялись без изменений во время транспортировки.

Источник: MDN

+1

В любом случае вы можете показать свое решение, я имею дело с той же проблемой в настоящее время. – Lion789

1

Это, очевидно, массивно поздно, однако я просто наткнулся на этот вопрос сам, вот как я получил эту работу;

ImageMagick.resize(params, function(err, stdout, stderr) { 
    // Handle errors 

    // Save the output of imagemagick to S3 
    S3.putObject({ 
     Bucket: bucketName, 
     Key: fileName, 
     Body: new Buffer(stdout, "binary") 
    }).promise().then(function(data){ 
     // Success 
    }).catch(function(err){ 
     // Error 
    }); 
}); 

Ключевой частью этого является, очевидно,; new Buffer(stdout, "binary"). Если вы не знаете, будет ли ответ буфером или нет, вы можете использовать метод Buffer.isBuffer и сделать следующее;

var body = (Buffer.isBuffer(stdout) ? stdout : new Buffer(stdout, "binary"));

Смежные вопросы