Передайте изображение через магию графики только наполовину

Я пытаюсь настроить поток преобразования для передачи изображения через GM https://github.com/aheckmann/gm. Так что я могу сделать что-то вроде:

readStream.pipe(resize()).pipe(writeStream);

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

'use strict';

var fs = require('fs')
  , gm = require('gm').subClass({imageMagick: true})
  , through2 = require('through2');



let readStream = fs.createReadStream('landscape.jpg');
let writeStream = fs.createWriteStream('landscape-out.jpg');


let resize = function(width, height) {

 return through2(function(chunk, enc, callback){
  gm(chunk)
   .resize(800)
   .gravity('Center')
   .crop(800, 500, 0, 0)
   .stream((err, stdout, stderr) => {
    
    stdout.on('data', chunk => {
     this.push(chunk);
    });

    stdout.on('end', () => {
     callback();
    });

  });
 });

} 



readStream.pipe(resize()).pipe(writeStream);

1 ответ

Решение

В

through2(function(chunk, enc, callback){

chunk это только небольшая часть изображения.

Таким образом, ваше поведение кажется нормальным, вы изменяете размеры фрагмента изображения, а не самого изображения.

Это сказал, в документе,

// GOTCHA:
// when working with input streams and any 'identify'
// operation (size, format, etc), you must pass "{bufferStream: true}" if
// you also need to convert (write() or stream()) the image afterwards
// NOTE: this buffers the readStream in memory!
var readStream = fs.createReadStream('/path/to/my/img.jpg');
gm(readStream)
.size({bufferStream: true}, function(err, size) {
  this.resize(size.width / 2, size.height / 2)
  this.write('/path/to/resized.jpg', function (err) {
    if (!err) console.log('done');
  });
});

но он собирается буферизовать изображение в памяти, поэтому он не оптимален.

Поскольку вы используете imagemagick, вы просто должны позволить ему управлять всей этой частью обработки. А потом fs.readStream, вывод.

Из документа

var writeStream = fs.createWriteStream('/path/to/my/reformatted.png');
gm('/path/to/my/img.jpg')
.stream('png')
.pipe(writeStream);
Другие вопросы по тегам