在 graphicsmagick 中从远程流创建 GIF
Posted
技术标签:
【中文标题】在 graphicsmagick 中从远程流创建 GIF【英文标题】:Creating a GIF from remote stream in graphicsmagick 【发布时间】: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 【参考方案1】:我设法通过首先将图像转换为miff
并将它们连接成单个流来仅使用streams
使其工作。然后使用delay
再次将buffer
或stream
传递给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 但它不起作用。告诉我你有没有用。以上是关于在 graphicsmagick 中从远程流创建 GIF的主要内容,如果未能解决你的问题,请参考以下文章
在 CentOS6 上安装 GraphicsMagick-1.3.30
在 AWS Lambda 函数中从 S3 获取对象并发送到 Api Gateway