【问题标题】:Creating a GIF from remote stream in graphicsmagick在 graphicsmagick 中从远程流创建 GIF
【发布时间】:2018-04-03 14:52:57
【问题描述】:

我正在通过将每个图像下载到文件系统中的 tmp 文件夹,从节点中的远程文件创建一个 GIF。

我想绕过将图像保存到 tmp 文件夹并保存在内存中。这可能吗?

如您所见,我的 AWS 类中有一个下载功能,它保存到 tmp 文件夹:

download(key){
    return new Promise((resolve, reject) => {
      request.head(`${this.base_url}/${this.bucket}/${key}`, (err, res, body) => {
        request(`${this.base_url}/${this.bucket}/${key}`)
            .pipe(fs.createWriteStream(`tmp/${key}`)).on('close', resolve )
      })
    })
};

一旦它们全部下载完毕,我的 GifService 类中有一个 createGif 函数,它将每个文件路径添加为 gm 的自定义参数,添加 50 毫秒的延迟,调整大小然后输出为缓冲区,然后我将其上传到 AWS s3.

import gm from 'gm';

...

constructor(){
    this.gm = gm()
}

generateGif(images, prefix){

    return new Promise((resolve, reject) => {

        // for each image we want in array, we pass to gm
        images.forEach(image => {
            this.gm.in(`tmp/${image.Key}`)
        })

        // Now we create the gif with 50sec delay between images, sized to 600px x 2
        this.gm
            .delay(50)
            .resize(600,600)
            .toBuffer('gif', async (err, buffer) => {
        if (err) reject(err)

        const params = {
                ACL: 'public-read',
                Bucket: config.aws_bucket,
                ContentType: 'image/gif',
                Key: `${prefix}/${uuid()}.gif`,
                Body: buffer
              }

              try{
                // uplaod to S3
            const upload = await this.aws.upload(params)

            // resolve s3 URL
            resolve(upload)

              }catch(err) {
                console.log('err', err)
                reject(err)
              }

      });
    })

}

理想情况下,如果我可以将远程文件流作为自定义参数传递,或者将缓冲区作为自定义参数传递,而不是我当前在 tmp 文件路径中传递的方式:

images.forEach(image => {
    this.gm.in(`tmp/${image.Key}`)
})

【问题讨论】:

  • 更新了我的帖子,展示我如何实例化 gm / graphicsmagick

标签: node.js imagemagick graphicsmagick gm node-imagemagick


【解决方案1】:

我设法通过首先将图像转换为miff 并将它们连接成单个流来仅使用streams 使其工作。然后使用delay 再次将bufferstream 传递给gm 就可以了。

您需要安装 concat-stream npm 才能正常工作。

抱歉,混合了 ES5 代码。

import gm from 'gm';
var concat = require('concat-stream');
...

constructor() {
    this.gm = gm()
}

start() {

    return getYourReadAbleStreamsSomehow().then(streams => {

        return generateGif(streams);

    }).then(gifBuffer => {

        return uploadToAWS(gifBuffer, prefix);

    }).catch(err => {
        console.log(err)
    })

}

uploadToAWS(buffer, prefix) {
    const params = {
        ACL: 'public-read',
        Bucket: config.aws_bucket,
        ContentType: 'image/gif',
        Key: `${prefix}/${uuid()}.gif`,
        Body: buffer
    }

    try {
        // uplaod to S3
        const upload = await this.aws.upload(params)

        // resolve s3 URL
        resolve(upload)

    } catch (err) {
        console.log('err', err)
        reject(err)
    }
}

generateGif(imageStreams, delay) {

    return new Promise((resolve, reject) => {

        var write = concat(function(buffer) {
            gm(buffer)
                .delay(delay)
                .toBuffer('gif', function(err, buffer) {

                    if (err) 
                        reject(err);

                    resolve(buffer);

                })
        })

        //Convert to miff and concat streams
        var i = 0;
        var streamHandler = function() {

            gm(imageStreams[i])
                .resize('600', '600')
                .stream('miff', function(err, stdout, stderr) {
                    if (err)
                        reject(err)

                    var lastOne = i === streams.length - 1;

                    if (!lastOne)
                        stdout.once('end', streamHandler)

                    stdout.pipe(write, {
                        end: lastOne
                    });

                    i++;

                });
        }

        streamHandler();

    })

}

【讨论】:

  • 如果我错了,请纠正我,但基本上streamHandler 正在从我所有的原始图像缓冲区中创建 1 个流?
  • 是的,它将每个图像转换为miff,然后可以用于转换为gif。我尝试使用 png 但它不起作用。告诉我你有没有用。
猜你喜欢
  • 2021-09-27
  • 1970-01-01
  • 1970-01-01
  • 2016-05-31
  • 1970-01-01
  • 1970-01-01
  • 2016-12-09
  • 1970-01-01
相关资源
最近更新 更多