我一直在尝试编写基于Sharp的图像处理引擎。主要思想是将图像作为多部分数据,对其进行格式化,然后将结果作为zip文件返回。下面的代码在我的本地计算机上似乎运行良好,但是一旦将其部署到Firebase,返回的zip文件将为空。可能是什么原因?
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
const os = require('os');
const fs = require('fs');
const Busboy = require('busboy');
const sharp = require('sharp');
const path = require('path');
const JSZip = require('jszip');
admin.initializeApp();
exports.processImage = functions.https.onRequest((req, res) => {
if (req.method === 'POST') {
const busboy = new Busboy({ headers: req.headers });
const tmpdir = os.tmpdir();
console.log('Writing files to tmpdir:', tmpdir);
const uploads = {};
const fileWrites = [];
const zip = new JSZip();
let index = 1;
busboy.on('file', (fieldname, file, filename) => {
console.log(`Processed file ${filename}`);
const filepath = path.join(tmpdir, filename);
uploads[fieldname] = filepath;
const writeStream = fs.createWriteStream(filepath);
const sharpStream = sharp()
.resize(480, 480)
.extend({
top: 16,
bottom: 16,
left: 16,
right: 16,
background: { r: 0, g: 0, b: 0, alpha: 0 }
})
.webp({ quality: 50 });
file.pipe(sharpStream).pipe(writeStream);
sharpStream.on('data', function(data) {
console.log('Processing', data.length, 'bytes');
});
const promise = new Promise((resolve, reject) => {
writeStream.on('finish', resolve);
writeStream.on('error', reject);
});
fileWrites.push(promise);
});
// Triggered once all uploaded files are processed by Busboy.
// We still need to wait for the disk writes (saves) to complete.
busboy.on('finish', () => {
Promise.all(fileWrites)
.then(() => {
for(const file in uploads) {
const filename = uploads[file];
let reader = fs.createReadStream(filename);
zip.file(`image${index++}.webp`, reader);
console.log(`${filename} written`);
}
let zipName = path.join(tmpdir, 'response.zip');
zip.generateNodeStream({ type: 'nodebuffer', streamFiles: true })
.pipe(fs.createWriteStream(zipName))
.on('finish', function () {
res.download(zipName);
});
})
.catch(err => {
console.error(err);
res.status(500).end();
});
});
req.pipe(busboy);
} else {
// Return a "method not allowed" error
res.status(405).end();
}
});