使用GraphicsMagick处理GridFS文件并将其作为新文件存储

我试图通过gridfs-stream ( https://github.com/aheckmann/gridfs-stream )读取一个GridFS文件,用gm旋转它90°并将其作为一个新的GridFS文件存储。

我的结果看起来非常不稳定…所以我在寻求帮助来优化这个小小的代码片段。

而这个代码的第二件事:我需要一种“开关”。 这段代码对图像进行旋转操作。 但我需要传递参数来做旋转,resize或其他。 我如何整合这个?

 import Grid from 'gridfs-stream' import { MongoInternals } from 'meteor/mongo' const id = '12345' const gfs = Grid( MongoInternals.defaultRemoteCollectionDriver().mongo.db, MongoInternals.NpmModule ) const readStream = gfs.createReadStream({ _id: id }) readStream.on('error', function (err) { console.error('Could not read stream', err) throw Meteor.Error(err) }) gm(readStream) .rotate('#ffffff', 90) .stream(function (err, stdout, stderr) { if (err) { console.error('Could not write stream') throw Meteor.Error(err) } const writeStream = gfs.createWriteStream() const newFileId = writeStream.id writeStream.on('finish', function () { console.log('New file created with ID ' + newFileId) } ) stdout.pipe(writeStream) }) 

我没有一个项目设置来testing这个,但它看起来是正确的。

复杂的stream媒体往往看起来相当丑陋。 除了不要让它失去控制外,你可以做的不是很多。 但是,让我们看看我们可以做什么来美化一路上,而添加额外的function。

  • 由于您是在顶层创build读取stream,我认为将您的写入stream置于顶层也更为清晰。 你可以将它们组合在一个对象中。

  • 胖箭头function往往看起来更干净,所以我把这些function放在匿名函数中。 请注意,胖箭头没有this绑定。 所以如果你需要访问你的stream的this ,你需要恢复使用function关键字。

  • 使用rsws来表示readstreamwritestream是很常见的约定。 所以我认为这是一个安全的缩写,在适当的地方使用。

  • 为了增加使用多个选项的能力,我们做了一个包装函数,它接受我们的插播和选项并返回stream出。 一个插件,你可以说。

  • 通过使我们的函数调用将对象parsing为参数,我们可以按名称来分配它们。 更容易说出发生了什么事情。

  • 我们使用Object.keys来获取一个选项名称的数组。 然后使用名称来遍历我们的选项,通过将参数数组spreadgm方法来应用每个选项。

  • gm自述文件说,如果没有callback,它会返回一个stream。 尼斯。 :)我们将返回整个stream链,准备pipe道输出我们想要的任何输出。

 import Grid from 'gridfs-stream' import gm from 'gm' import { MongoInternals } from 'meteor/mongo' const id = '12345' const gfs = Grid( MongoInternals.defaultRemoteCollectionDriver().mongo.db, MongoInternals.NpmModule ) const gfsStreams = { read: _id => gfs.createReadStream({ _id }) .on('error', err => { console.error('Could not read stream', err) throw Meteor.Error(err) }), write: () => { const ws = gfs.createWriteStream() const newFileId = ws.id ws.on('finish', () => console.log('New file created with ID ' + newFileId) ) .on('error' => { console.error('Could not write stream') throw Meteor.Error(err) }) return ws } } const transformedStream = gmTransform({ filestream: gfsStreams.read(id), gmOptions: { magnify: [], rotate: ['ffffff', 90], blur: [7, 3] crop: [300, 300, 150, 130] }, output: stdout }) stdout.pipe(transformedStream) function gmTrasform ({filestream, gmOptions}){ let gmStream = gm(filestream) .on('error', { console.error('Could not transform image') throw Meteor.Error(err) }) Object.keys(gmOptions) .forEach(opt => { gmStream = gmStream[opt](...gmOptions[i]) }) return gmStream.stream() .pipe(gfsStreams.write()) }