我正在尝试使用 canvas
模块在 node.js 脚本中创建一个 PNG 文件。
我有一个文件 image.js
来处理图像创建:
const { createCanvas, loadImage } = require('canvas');
const fs = require('fs');
function generateImage(param1, param2) {
const canvas = createCanvas(4096, 4096);
const ctx = canvas.getContext('2d');
// ...
return new Promise(function (resolve, reject) {
loadImage('base.png').then((image) => {
ctx.drawImage(image, 40, 40, 200, 200);
let out = fs.createWriteStream(__dirname + '/temp.png');
let stream = canvas.pngStream();
stream.on('data', function (chunk) {
out.write(chunk);
});
stream.on('end', function () {
console.log('saved png');
out.close(); // i probably don't need both, but neither seems to work properly...
out.end();
resolve();
});
});
});
}
module.exports = generateImage;
当我将 generateImage('a', 'b');
附加到该文件的末尾,然后单独运行它 (node image.js
) 时,它按预期工作并生成我的图像。但是,当我尝试从不同的文件(在同一文件夹中)调用它时,文件句柄似乎没有关闭,并且在脚本运行时磁盘上的图像是一个空文件。
main.js
(简化版):
const generateImage = require('./image');
const fs = require('fs');
async function main() {
var stats = fs.statSync("temp.png");
console.log(stats["size"]); // output: 0, expected: > 0
}
generateImage("text", "text").then(() => main());
我是 node.js 的新手,所以我很可能遗漏了一些明显的东西。
最佳答案
根据 Bergi 的建议,我需要为 out
流的 close
事件添加另一个事件监听器,并且只调用一次 resolve()
即被触发。我还链接了 promise ,而不是像问题中那样将它们嵌入。
function generateImage(param1, param2) {
const canvas = createCanvas(4096, 4096);
const ctx = canvas.getContext('2d');
// ...
return loadImage('base.png').then((image) => new Promise(function (resolve, reject) {
ctx.drawImage(image, 40, 40, 200, 200);
let out = fs.createWriteStream(__dirname + '/temp.png');
let stream = canvas.pngStream();
stream.on('data', (chunk) => out.write(chunk));
stream.on('end', () => out.end());
out.on('close', () => resolve()); // this was missing
}));
}
关于javascript - 如何用 promise 关闭文件句柄?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51428115/