graphicsmagick crop取决于原始图像大小(重新读取流)

时间:2015-02-26 23:30:41

标签: node.js image-processing meteor graphicsmagick

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

这打破了:

crop

维度返回但第二次使用readStream返回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); })

我已经看到了一些与此相关的其他答案,但没有人帮助我,因为包裹迫使我Error: gm().stream() or gm().write() with a non-readable stream;我不能只做'.writeAsync()'我尝试了各种不起作用的其他技巧,包括:

  • 克隆流以获取大小,然后使用原始进行同步转换并保存(在计时器中)
  • 同步调用整个事物(愚蠢的想法,但值得一试)

如果有人有任何想法,我真的很感激你的意见。

谢谢! db

2 个答案:

答案 0 :(得分:2)

这有效并且不依赖于客户端,这使它更安全:

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

答案 1 :(得分:0)

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

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

不太理想,但有效。