如何通过Cloud Function获取Firebase Storage中图片的宽高?
如何通过Cloud Function获取Firebase Storage中图片的宽高?
你遇到的问题我太懂了——直接对图片URL调用naturalHeight和naturalWidth肯定拿不到值,因为这俩是浏览器环境里Image对象的专属属性,而Cloud Function跑在Node.js服务器环境里,根本没有这个对象,自然返回undefined啦。
先看看你当前的代码和遇到的错误:
你的函数代码:
exports.imageHeightWidth = functions.https.onRequest(async (req, res) => { const imagesCollection = await firestore.collection("images").get(); const imageDocs = imagesCollection.docs; for (const image of imageDocs) { const imageDoc = image.data(); const imageLink = imageDoc.imageURL; console.log("imageLink: ", imageLink); const height = imageLink.naturalHeight; const width = imageLink.naturalWidth; console.log("image Dimensions: ", height, width); } res.send("Hello"); });
运行后得到的错误输出:
image Dimensions: undefined undefined
那该怎么解决呢?在Node.js环境里,我们可以用专门的图片处理库来获取图片宽高,比如sharp——这是个高性能的Node.js图片处理工具,非常适合在Cloud Function里使用。
下面是具体的解决步骤:
1. 安装依赖
首先在你的Cloud Function项目根目录下安装sharp:
npm install sharp
2. 修改你的Cloud Function代码
下面是修改后的完整代码,我加了详细注释,你可以参考:
const functions = require("firebase-functions"); const admin = require("firebase-admin"); const sharp = require("sharp"); // 初始化Firebase Admin admin.initializeApp(); const firestore = admin.firestore(); const storage = admin.storage(); exports.imageHeightWidth = functions.https.onRequest(async (req, res) => { try { // 获取Firestore中所有图片文档 const imagesCollection = await firestore.collection("images").get(); const imageDocs = imagesCollection.docs; // 遍历每个图片文档 for (const imageDoc of imageDocs) { const docData = imageDoc.data(); const imageURL = docData.imageURL; console.log("当前处理的图片URL: ", imageURL); // 从图片URL中解析出Firebase Storage的文件路径 // 注:如果你的Firestore文档里直接存了Storage的文件路径(比如images/xxx.jpg),可以直接用这个路径,不用解析URL const urlObj = new URL(imageURL); const encodedFilePath = urlObj.pathname.split("/o/")[1].split("?")[0]; const filePath = decodeURIComponent(encodedFilePath); // 获取Storage的文件实例 const storageBucket = storage.bucket(); const imageFile = storageBucket.file(filePath); // 下载图片到缓冲区 const [imageBuffer] = await imageFile.download(); // 用sharp获取图片的宽高元数据 const imageMetadata = await sharp(imageBuffer).metadata(); const { width, height } = imageMetadata; console.log(`图片${imageDoc.id}的尺寸: ${width}x${height}`); // 可选:把获取到的宽高更新回Firestore文档,方便后续使用 await imageDoc.ref.update({ width: width, height: height }); } res.send("所有图片尺寸处理完成!"); } catch (error) { console.error("处理过程中出错: ", error); res.status(500).send(`处理失败:${error.message}`); } });
关键说明
- 为什么不用HTTP请求获取图片?直接用Firebase Storage SDK下载文件比通过HTTP请求更可靠,还能避免跨域或者URL过期的问题。
sharp的效率很高,处理大量图片也不会有性能问题,非常适配Cloud Function的运行环境。- 代码里加了错误处理,就算某一张图片处理失败,整个函数也不会崩溃,还能输出错误信息方便排查。
备注:内容来源于stack exchange,提问作者Coolkid
相关产品推荐
相关产品推荐

