Firebase函数 - 在上传到存储时调整大小并覆盖现有图像

4

所以我按照Google官方示例创建了一个Cloud Storage触发的Firebase函数,该函数将从上传的图像创建调整大小的缩略图并将其上传到Storage中。这是简化后的代码:

exports.generateThumbnail = functions.storage.object().onChange(event => {

    // get the uploaded file data (bucket, name, type...)

    // return if the file is not an image or name begins with "thumb_"

    // download the uploaded image in a temporary local file,
    // resize it using ImageMagick
    // upload it to storage with the name "thumb_<filename>"

}

然而,当新的缩略图上传时,该函数再次被触发,从而形成循环。他们通过检查上传的文件是否具有“thumb_”前缀来避免这种情况。

然后,您将获得两个图像(原始图像和缩略图),我希望用缩略图重写现有图像,以便只有一张带有原始路径的图像。

我不知道如何做到这一点,因为我不知道如何在没有名称更改的情况下避免重新上传循环。我可以在上传缩略图后删除原始图像,但指向原始图像的链接已经返回并保存在实时数据库中(这些图像是用户的个人资料图片)。


您只需要存储缩略图图像吗? - Bruno Ferreira
@BrunoFerreira 是的,我只想要缩略图,但是我希望它具有存储中原始图像的路径,基本上是覆盖原始数据。 - mj3c
你可以尝试获取原始图像的路径,将缩略图上传到原始图像的路径并删除原始图像。例如,如果原始路径为.../images,则可以创建缩略图并上传到.../images路径,然后删除原始图像。如果您想要更多内容,我可以提供答案。 - Bruno Ferreira
@BrunoFerreira 我不确定我们是否理解彼此,这个函数是在原始图像(假设为/avatars/zantsu.jpg)上传后立即触发的,该函数创建一个调整大小的图像并将数据上传到/avatars/thumb_zantsu.jpg,如果我删除前缀并将缩略图上传到/avatars/zantsu.jpg,那么它将成功覆盖图像,但然后函数会再次触发,我不知道如何退出它,以便它不会重新开始重新上传。 - mj3c
你可以获取 /avatars/zantsu.jpg,创建一个缩略图 avatars/thumb_zantsu.jpg,上传该缩略图,使 /avatars/ 路径下有两个图像,即缩略图和原始图像。当成功上传缩略图后,删除原始图像 /avatars/zantsu.jpg,只保留 avatars/thumb_zantsu.jpg 缩略图。这就是我的意思。 - Bruno Ferreira
1个回答

12

在查看了@google-cloud/storage npm模块中的bucket.js文档后,我最终成功地用缩略图覆盖了原始文件/路径,并避免了循环。

上传缩略图时附加自定义元数据,然后在下一次函数触发时测试该元数据即可完成操作。

我将只发布我所做的更改,其余部分与链接示例相同。

以下是测试代码:

const filePath = event.data.name
const metadata = event.data.metadata

if (metadata.isThumb) {
    console.log('Exiting: Already a thumbnail')
    return
}

接下来是当 spawn Promise 返回时的部分:

    return spawn(/* ... */)
}).then(_ => {
    console.log('Thumbnail created locally.')
    metadata.isThumb = true  // We add custom metadata
    const options = {
        destination: filePath,  // Destination is the same as original
        metadata: { metadata: metadata }
    }
    // We overwrite the (bigger) original image but keep the path
    return bucket.upload(/* localThumb */, options)
})

1
非常感谢,我也一直在寻找覆盖图片的方法,你的解决方案完美地解决了我的问题!干杯! - Gregordy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接