【问题标题】:Manipulate GridFS file with GraphicsMagick and store it as new file使用 GraphicsMagick 操作 GridFS 文件并将其存储为新文件
【发布时间】:2016-02-29 04:25:13
【问题描述】:

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

我的结果看起来很“不时尚”...所以我请求帮助优化这个小代码 sn-p...

这段代码的第二件事是:我需要一种“开关”。此代码对图像进行旋转操作。但我需要传递一个参数来进行旋转、调整大小或其他操作。我该如何整合它?

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

【问题讨论】:

  • 你知道,这真的不清楚,你的问题是什么。 “不时尚”是什么意思?您能否将您的结果示例以及所需的行为/外观包括在内?

标签: javascript node.js meteor gridfs-stream gm


【解决方案1】:

我没有设置项目来测试它,但它看起来不错。

复杂的流媒体往往看起来很丑陋。除了尽量不让它失控之外,你无能为力。但是,让我们看看在添加附加功能的同时我们可以做些什么来美化。

  • 由于您是在顶层创建读取流,我认为将写入流也放在顶层会更干净。您可以将它们组合在一个对象中。

  • 胖箭头函数看起来更简洁,所以我将它们放入匿名函数中。请注意,胖箭头没有 this 绑定。因此,如果您需要访问流的this,则需要恢复为使用function 关键字。

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

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

  • 通过使我们的函数调用将对象解构为参数,我们可以按名称分配它们。更容易知道发生了什么。

  • 我们使用Object.keys 来获取选项名称数组。然后使用名称逐步执行我们的选项,通过spread将参数数组应用到gm 方法中来应用每个选项。

  • gm readme 表示,如果没有给出回调,它将返回一个流以方便使用。好的。 :) 我们将返回整个流链,准备好管道到我们想要的任何输出。

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

【讨论】:

    猜你喜欢
    • 2016-07-12
    • 2012-09-07
    • 2015-04-06
    • 2012-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-11
    • 2013-10-27
    相关资源
    最近更新 更多