graphicsmagick 根据原始图像大小进行裁剪(重新使用读取流)

graphicsmagick crop depending on original image size (resuse readstream)

我正在使用 Meteor 的 collection-fs 包上传图片,我想使用 gm(readStrem).crop() 从每张图片的中心剪切一个缩略图。问题是,cropxy 偏移取决于原始图像的大小,图像大小会有所不同,我不能两次使用相同的 reasdStream。

这中断了:

var xOff = 0;
var yOff = 0;
var thumbnailWidth = 450;
var thumbnailHeight = 600;
gm(readStream).size(function (err, dimensions) {
   if ( dimensions ) {
     xOff = (dimensions.width - thumbnailWidth) / 2;
     yOff = (dimensions.height - thumbnailHeight) / 2;
   }
   gm(readStream)
     .crop(thumbnailWidth, thumbnailHeight, xOff, yOff)
     .stream()
     .pipe(writeStream);
})

维度return但是第二次使用readStreamreturnsError: gm().stream() or gm().write() with a non-readable stream

我看到了一些与此相关的其他答案,但 none 帮助了我,因为包裹迫使我 pipe(writeStream);我不能只做 '.writeAsync()' 我尝试了各种其他无效的技巧,包括:

如果有人有任何想法,我将非常感谢您的意见。

谢谢! 数据库

解决方案是在客户端确定文件大小,在写入之前将这些详细信息附加到 fileObj,然后在写入期间在服务器上正常调用 crop。

var cropInfo = fileObj.cropInfo
gm(readStream)
     .crop(cropInfo.width, cropInfo.height, cropInfo.x, cropInfo.y)
     .stream()
     .pipe(writeStream);

不太理想,但它有效。

这有效且不依赖于客户端,因此更安全:

var xOff = 0;
var yOff = 0;
var thumbnailWidth = 450;
var thumbnailHeight = 600;
gm(readStream, fileObj.name()).size(
  {bufferStream: true},
  function (err, dimensions) {
    if (dimensions) {
      xOff = (dimensions.width - thumbnailWidth) / 2;
      yOff = (dimensions.height - thumbnailHeight) / 2;
    }
    this.crop(thumbnailWidth, thumbnailHeight, xOff, yOff);
    this.stream((err, stdout, stderr) => {
      stdout.pipe(writeStream);
    });
  }
);