繁体   English   中英

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

[英]Resize all images stored in Firebase Storage

我已经在 Firebase 存储桶上上传了大约 10k 个高分辨率图像。 到目前为止,由于带宽很高,我需要在不删除原始图像的情况下缩小存储桶中的这些图像。

Firebase 图像调整大小扩展 function 解决了这个问题,但仅适用于那些新上传的图像 它不适用于已经上传的图像。

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

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

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

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

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

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

您最终要做的是编写一些代码来列出所有对象,然后为每个对象下载它,在本地修改它,然后将修改后的版本上传回存储桶。 它可能很长,具体取决于您拥有多少内容。 如果您只想这样做一次,最好只编写一个脚本并在Cloud Shell中运行它,这样您就可以最大限度地减少传输对象所花费的时间。

这是一个快速而肮脏的 NodeJS function,它将触发 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]);
  }
}

或者,您可以创建一个 Google Cloud Function(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

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

因此,正如gcp 文档所说:

此事件在桶中创建新的 object(或现有 object 被覆盖,并创建该 object 的新一代)时发送

For overwritten an object we need to create a copy of this object with the same name, to accomplish this action, we can use Node.js Admin SDK with the methode getFiles() thanks Renaud Tarnec , and then 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();

firebase 调整大小扩展将自动为您执行此操作:

https://firebase.google.com/products/extensions/firebase-storage-resize-images

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM