我在Firebase存储桶上上传了大约1万张高分辨率图像。到目前为止,由于带宽较高,我需要按比例缩小存储桶中的这些图像,而不会删除原始图像。
Firebase图像调整大小扩展功能可解决此问题,但仅适用于新上传的图像。不适用于已上传的图像。
那么,有没有办法做到这一点。我知道我们使用云功能来调整图像的大小,但是我不确定如何实现这一点,因为没有触发功能可以使云功能正常工作。
答案 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",
});
答案 4 :(得分:0)
Firebase 图像大小调整扩展程序在事件 "google.storage.object.finalize" 上触发。
<块引用>当存储桶中创建新对象(或覆盖现有对象,并创建该对象的新一代)时发送此事件
对于覆盖的对象,我们需要创建该对象的同名副本,要完成此操作,我们可以使用 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();