将生成的PNG从lambda上的节点上传到amazon S3(Upload generated PNG to amazon S3 from node on lambda)

编程入门 行业动态 更新时间:2024-10-28 14:34:40
将生成的PNG从lambda上的节点上传到amazon S3(Upload generated PNG to amazon S3 from node on lambda)

我正在从他们各自的URL下载2个PNG图像,然后使用pixelmatch比较它们并生成第三张图像。

然后我试图将第三张图片上传到S3存储桶,但我很挣扎。 代码如下。

promise1和promise2分别是获得png1和png2的两个调用。 下面使用的dimensions1数组是在promise1创建的。 PNG是pngjs包。

const promArr = [promise1, promise2]; Promise.all(promArr).then(() => { const diff = new PNG({ width: dimensions1[0], height: dimensions1[1] }); const pix = pixelmatch(png1.data, png2.data, diff.data, dimensions1[0], dimensions1[1], { threshold: 0.1 }); const size = dimensions1[0] * dimensions1[1]; diff.pack().pipe(fs.createWriteStream(`/tmp/${targetHash}.png`)); const percentage = ((pix / size) * 100); const fileBuffer = fs.readFileSync(`/tmp/${targetHash}.png`); const s3 = new AWS.S3(); s3.putObject({ ACL: 'public-read', Key: targetFilename, Body: fileBuffer, Bucket: targetBucket, ContentType: 'image/png', }, (err) => { if (err) { console.warn(err); cb(err); } else { cb(null, { percentage, hash: `${targetFilename}`, key: `${targetFilename}`, bucket: targetBucket, url: `${event.stageVariables.endpoint}${targetFilename}`, }); } return; }); }) .catch((err) => { console.warn(`error: ${err}`); cb(err); });

这会返回一个指向mac的报告为空的图像的URL。 这表明我有一个异步问题。

我也尝试传递diff.pack()作为正文,并得到错误: Cannot determine length of [object Object] 。 我在这里找到了关于这个错误的讨论。

我感觉真的很接近解决方案,但我并没有完全达到目标。 谁能帮忙? 谢谢

I'm downloading 2 png images from their respective URLs then using pixelmatch to compare them and generate a 3rd image.

I'm then trying to upload the third image to an S3 bucket but I'm struggling. Code follows.

promise1 and promise2 are the two calls to get png1 and png2 respectively. The dimensions1 array used below is created in promise1. PNG is the pngjs package.

const promArr = [promise1, promise2]; Promise.all(promArr).then(() => { const diff = new PNG({ width: dimensions1[0], height: dimensions1[1] }); const pix = pixelmatch(png1.data, png2.data, diff.data, dimensions1[0], dimensions1[1], { threshold: 0.1 }); const size = dimensions1[0] * dimensions1[1]; diff.pack().pipe(fs.createWriteStream(`/tmp/${targetHash}.png`)); const percentage = ((pix / size) * 100); const fileBuffer = fs.readFileSync(`/tmp/${targetHash}.png`); const s3 = new AWS.S3(); s3.putObject({ ACL: 'public-read', Key: targetFilename, Body: fileBuffer, Bucket: targetBucket, ContentType: 'image/png', }, (err) => { if (err) { console.warn(err); cb(err); } else { cb(null, { percentage, hash: `${targetFilename}`, key: `${targetFilename}`, bucket: targetBucket, url: `${event.stageVariables.endpoint}${targetFilename}`, }); } return; }); }) .catch((err) => { console.warn(`error: ${err}`); cb(err); });

This returns a URL to the image which Preview on mac reports to be empty. This suggests to me that I have an async issue.

I have also tried passing diff.pack() as the body and got the error: Cannot determine length of [object Object]. I found a discussion of this error here.

I feel really close to a solution but I'm not quite getting there. Can anyone help? Thank you

最满意答案

见下面的解决方案 这是一个异步问题。 从这里采取笔记。 一旦创建临时文件的管道已经完成s3的东西开始。 注意这里提到的createReadStream的使用。

const promArr = [promise1, promise2]; Promise.all(promArr).then(() => { const diff = new PNG({ width: dimensions1[0], height: dimensions1[1] }); const pix = pixelmatch(png1.data, png2.data, diff.data, dimensions1[0], dimensions1[1], { threshold: 0.1 }); const size = dimensions1[0] * dimensions1[1]; const percentage = ((pix / size) * 100); diff.pack().pipe(fs.createWriteStream(`/tmp/${targetHash}.png`).on('finish', () => { const fileBuffer = fs.createReadStream(`/tmp/${targetHash}.png`); const s3 = new AWS.S3(); s3.putObject({ ACL: 'public-read', Key: targetFilename, Body: fileBuffer, Bucket: targetBucket, ContentType: 'image/png', }, (err) => { if (err) { console.warn(err); cb(err); } else { cb(null, { percentage, hash: `${targetFilename}`, key: `${targetFilename}`, bucket: targetBucket, url: `${event.stageVariables.endpoint}${targetFilename}`, }); } return; }); })); }) .catch((err) => { console.warn(`error: ${err}`); cb(err); });

我并不完全满意于写入tmp然后再读出来,但它似乎是现在处理aws-sdk限制的最简单方法。

See solution below. It was an async issue. Took notes from here. Once the pipe to create the temporary file has finished the s3 stuff kicks off. NB the use of createReadStream which is mentioned here.

const promArr = [promise1, promise2]; Promise.all(promArr).then(() => { const diff = new PNG({ width: dimensions1[0], height: dimensions1[1] }); const pix = pixelmatch(png1.data, png2.data, diff.data, dimensions1[0], dimensions1[1], { threshold: 0.1 }); const size = dimensions1[0] * dimensions1[1]; const percentage = ((pix / size) * 100); diff.pack().pipe(fs.createWriteStream(`/tmp/${targetHash}.png`).on('finish', () => { const fileBuffer = fs.createReadStream(`/tmp/${targetHash}.png`); const s3 = new AWS.S3(); s3.putObject({ ACL: 'public-read', Key: targetFilename, Body: fileBuffer, Bucket: targetBucket, ContentType: 'image/png', }, (err) => { if (err) { console.warn(err); cb(err); } else { cb(null, { percentage, hash: `${targetFilename}`, key: `${targetFilename}`, bucket: targetBucket, url: `${event.stageVariables.endpoint}${targetFilename}`, }); } return; }); })); }) .catch((err) => { console.warn(`error: ${err}`); cb(err); });

I'm not completely happy with writing to tmp then reading back out again but it seems to be the easiest way of dealing with aws-sdk limitations for now.

更多推荐

本文发布于:2023-08-07 20:11:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1465817.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:节点   amazon   PNG   lambda   generated

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!