调整Firebase存储中存储的所有图像的大小

时间:2020-07-22 21:06:59

标签: image firebase google-cloud-storage image-resizing

我在Firebase存储桶上上传了大约1万张高分辨率图像。到目前为止,由于带宽较高,我需要按比例缩小存储桶中的这些图像,而不会删除原始图像。

Firebase图像调整大小扩展功能可解决此问题,但仅适用于新上传的图像。不适用于已上传的图像。

那么,有没有办法做到这一点。我知道我们使用云功能来调整图像的大小,但是我不确定如何实现这一点,因为没有触发功能可以使云功能正常工作。

5 个答案:

答案 0 :(得分:2)

有一个官方的Cloud Function sample,其中显示了如何调整图像大小(实际上与Resize Images扩展基础的Cloud Function非常相似)。

此示例Cloud Function在将文件上传到Firebase项目的默认Cloud Storage存储桶时触发,但是应该很容易调整其触发。

例如,您可以编写一个callable Cloud Function,它使用Node.js Admin SDK getFiles()方法列出存储桶中的所有文件并调整每个文件的大小。

由于要处理的文件很多,因此很可能应该分批处理,因为执行Cloud Function的时间限制为9分钟。

答案 1 :(得分:0)

如果您的内容已经上传到Cloud Storage存储桶,则没有任何类型的Cloud Function或简单的代码可以自动完成所有这些任务。 Cloud Functions仅响应存储桶中发生的事件,例如对象的创建或删除。

您最终要做的是向list all your objects写一些代码,然后对每个download it进行本地修改,然后upload修改后的版本返回到桶。可能会很长,具体取决于您拥有多少内容。如果您只想一次执行此操作,则最好只编写脚本并在Cloud Shell中运行它,这样可以最大程度地减少转移对象所花费的时间。

答案 2 :(得分:0)

这是一个快速而肮脏的 NodeJS 函数,它将触发 Firebase 图像大小调整扩展。仅适用于 jpg/jpeg 文件。

我正在将文件复制到同一目的地。复制后重新设置之前的元数据很重要,因为它会在复制操作中丢失。

const storage = await getStorage();
const bucketName = `${process.env.PROJECT_ID}.appspot.com`; //replace this with the bucket you want to run on
const bucket = storage.bucket(bucketName);
const files = await bucket.getFiles();
for (const file of files[0]) {
  const isImage = file.name.toLowerCase().includes('jpg') || file.name.toLowerCase().includes('jpeg');
  const isThumb = file.name.toLowerCase().includes('thumbs');
  if (isImage && !isThumb) {
    console.info(`Copying ${file.name}`);
    const metadata = await file.getMetadata();
    await file.copy(file.name);
    await file.setMetadata(metadata[0]);
  }
}

答案 3 :(得分:0)

或者,您可以创建一个 Google Cloud 函数(URL 端点),用于获取将在运行时调整大小并缓存到 GCS 和 CDN 的图像。例如:

https://i.kriasoft.com/sample.jpg - 原始图像 https://i.kriasoft.com/w_200,h_100/sample.jpg - 动态调整大小的图像

$ npm install image-resizing --save
const { createHandler } = require("image-resizing");

module.exports.img = createHandler({
  // Where the source images are located.
  // E.g. gs://s.example.com/image.jpg
  sourceBucket: "s.example.com",

  // Where the transformed images need to be stored.
  // E.g. gs://c.example.com/image__w_80,h_60.jpg
  cacheBucket: "c.example.com",
});

https://github.com/kriasoft/image-resizing

答案 4 :(得分:0)

Firebase 图像大小调整扩展程序在事件 "google.storage.object.finalize" 上触发。

gcp documentation所说:

<块引用>

当存储桶中创建新对象(或覆盖现有对象,并创建该对象的新一代)时发送此事件

对于覆盖的对象,我们需要创建该对象的同名副本,要完成此操作,我们可以使用 Node.js Admin SDK 和方法 getFiles() 感谢 Renaud Tarnec,以及然后file.copy()

const { Storage } = require("@google-cloud/storage");
const storage = new Storage();

// Don't forget to replace with your bucket name
const bucket = storage.bucket("bucket-name.appspot.com"); 

const triggerBucketEvent = async () => {
  bucket.getFiles(
    {
      prefix: "public", // you can add a path prefix
      autoPaginate: false,
    },
    async (err, files) => {
      // Copy each file on same directory with the same name
      await Promise.all(files.map((file) => file.copy(file.metadata.name)));
    }
  );
};

triggerBucketEvent();